Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Swiftで実装するHTML特殊文字の高速処理
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
sonson
September 18, 2017
Programming
3
7.9k
Swiftで実装するHTML特殊文字の高速処理
iOSDC2017での発表スライドです.
sonson
September 18, 2017
Tweet
Share
More Decks by sonson
See All by sonson
計算グラフのJITコンパイラをLLVM on C++で作ろう
sonsongithub
2
610
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.5k
LLVM Tutorial 02 - わいわいswiftc
sonsongithub
1
440
LLVM Tutorial - わいわいswiftc
sonsongithub
0
340
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
First step of 3D touch
sonsongithub
0
680
Getting started with 3D Touch
sonsongithub
0
770
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
590
Other Decks in Programming
See All in Programming
「ブロックテーマでは再現できない」は本当か?
inc2734
0
1.1k
AIに仕事を丸投げしたら、本当に楽になれるのか
dip_tech
PRO
0
170
受け入れテスト駆動開発(ATDD)×AI駆動開発 AI時代のATDDの取り組み方を考える
kztakasaki
2
500
grapheme_strrev関数が採択されました(あと雑感)
youkidearitai
PRO
1
190
社内規程RAGの精度を73.3% → 100%に改善した話
oharu121
12
6.1k
Rails Girls Tokyo 18th GMO Pepabo Sponsor Talk
yutokyokutyo
0
180
Agent Skills Workshop - AIへの頼み方を仕組み化する
gotalab555
13
7.4k
オブザーバビリティ駆動開発って実際どうなの?
yohfee
2
630
New in Go 1.26 Implementing go fix in product development
sunecosuri
0
100
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
3
430
Rで始めるML・LLM活用入門
wakamatsu_takumu
0
120
メタプログラミングで実現する「コードを仕様にする」仕組み/nikkei-tech-talk43
nikkei_engineer_recruiting
0
130
Featured
See All Featured
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
エンジニアに許された特別な時間の終わり
watany
106
240k
Chasing Engaging Ingredients in Design
codingconduct
0
130
Organizational Design Perspectives: An Ontology of Organizational Design Elements
kimpetersen
PRO
1
620
Amusing Abliteration
ianozsvald
0
120
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
63
53k
Producing Creativity
orderedlist
PRO
348
40k
Joys of Absence: A Defence of Solitary Play
codingconduct
1
300
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
60
42k
Docker and Python
trallard
47
3.7k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
280
How to make the Groovebox
asonas
2
2k
Transcript
How to accelerate string processor in Swift. Tech. Yuichi Yoshida
Researcher, DENSO IT Laboratory, Inc. #iOSDC2017 @sonson_twit © 2014 DENSO IT Laboratory, Inc., All rights reserved. Redistribution or public display not permitted without written permission from DENSO IT Laboratory, Inc. SwiftͰ࣮͢ΔHTMLಛघจࣈͷߴॲཧ
ࣗݾհ • sonson • twitter: sonson_twit • github: sonsongithub •
portfolioʢ࠷ۙͷʣ • reddift(SwiftͰॻ͍ͨreddit.comͷAPIϥούʔ) • numsw(Swift PlaygroundsͰಈ͘ػցֶश༻notebook) • HTMLSpecialCharacters(ࠓͷ͓) • ࣄ • ը૾ೝࣝɾݕࡧɾػցֶशͷݚڀ։ൃ
None
None
త • 2tch • SwiftͰॻ͖͍ͨ • ࠷େ1000ߦͷςΩετΛॲཧ͢Δ • Δ͜ͱ •
ཁૉͷΓग़͠ɾɾɾσϦϛλ<>, վߦίʔυ • HTMLಛघจࣈUnescape • ຊจͷύʔεɼϨΠΞτ • 1000ݸ͋Δͱɼ1[msec/item]Ͱ1ඵ͔͔Δ • 30[msec]Ͱ1000ݸॲཧͰ͖Δͷ͕ඪ • ආ͚ΒΕͳ͍ਖ਼نදݱॲཧ͕͍
HTMLಛघจࣈ • W3CͰఆٛ͞Ε͍ͯΔ • &<>ͳͲͷςΩετʹͦͷ··ॻ͚ͳ͍ಛघͳจࣈ • Escape/Unescapeʔ& & & •
໊લ • 10ਐ͋Δ͍16ਐͷจࣈίʔυ & & escape & & unescape
՝ • Google Toolbox • SwiftʹҠ২؆୯ • ΄ͱΜͲมΘΒͳ͍ • ͔͔ͤͬͩ͘Β͍ͨ͘͠
• StringܕͰॲཧ͍ͯ͠ΔݶΓଟ͔ΘΒͳ͍ • Stringܕಉ͡จࣈΛ୳͢ίετେ͖͍ • decode͢ΔલͷੜσʔλͰॲཧ͢Ε͘ͳΔʂ
String͚ͩͰΔطଘख๏ J T B N Q B J
T B จࣈྻ จࣈྻ จࣈྻ Ұக֬ೝ จࣈྻ Ұக֬ೝ B N Q จࣈྻ B N Q E F H O P U ͕͞ࡾจࣈͷ ࣙॻ(จࣈྻ) ɾɾɾɾ ࣙॻ୳ࡧ ஔ J T B N Q B จࣈྻ
ੜσʔλΔύλʔϯ Y Y Y Y Y YE Y YC Y
Y Y Y Y Y Y Y [Unichar] [Unichar] Y YE Y [Unichar] ࣙॻ୳ࡧ ஔ J T B N Q B จࣈྻ Y Y Y Y Y YE Y YC Y Y [Unichar] Y YE Y Y Y Y Y YE Y ͕͞ࡾจࣈͷ ࣙॻ(จࣈྻ) ɾɾɾ J T B จࣈྻ encode decode Y ୳͢ YC ୳͢ Unichar Unichar
ൺֱ(iPhone7) FTDBQF ճ VOFTDBQF ճ ߦׂ ߦ )5.-λάআڈ :BIPPͷτοϓ 1SPQPTFE
Y Y Y Y จࣈྻͷ·· ॲཧ ※୯Ґ[msec] ※unescapeͷׅހͷNSAttributedStringΛͬͨࢀߟ
ίʔυ্ͷ՝Λߟ͑Α͏
StringΛutf16ͷunicharͷྻʹ͢Δ public var unescapeHTML: String { var buffer = [unichar](repeating:
0, count: utf16.count) NSString(string: self).getCharacters(&buffer) var end = buffer.endIndex let ampersand = unichar(UInt8(ascii: "&")) let semicolon = unichar(UInt8(ascii: ";")) let sharp = unichar(UInt8(ascii: "#")) let hexPrefixes = ["X", "x"].map { unichar(UInt8(ascii: $0)) } จࣈͰͳ͍ͷͰɼ”&”ͳͲͷจࣈίʔυσʔλ Λ͋Β͔͡Ί࡞͓ͯ͘͠
όοϑΝͷಈ͖ Y Y Y Y Y YE Y YC Y
Y Y Y Y Y YE Y YC Y Y &ͷ୳ࡧ Y Y Y Y Y YE Y YC Y Y Y Y Y Y YE Y YC Y Y ;ͷ୳ࡧ Y Y Y Y Y YE Y YC Y Y Y Y Y Y Y ஔ Y Y Y Y Y YE Y YC Y Y Y Y Y Y Y ࣍ͷ&ͷ୳ࡧ
ඞཁʹͳͬͯ͘Δॲཧ • Ϛονϯά • ಡΈऔͬͨescapeจࣈྻͱςʔϒϧͷϚονϯά Y Y Y Y Y
YE Y YC Y Y Y YE Y Y YE Y Y YE Y Y Y Y Y Y Y ɾɾɾɾ Table Ϛονϯά
จࣈྻͷҰகΛνΣοΫ͢Δίʔυ if let t = getTable(length: $0.count) { for i
in 0..<t.count { var match = true if memcmp($0.unescapingCodes, unichars, length) == 0 { return t[i].code } } } throw HTMLSpecialCharactersError.invalidEscapeSquenc ͬͱφ͍ײ͡Ͱ
จࣈྻͷҰகΛνΣοΫ͢Δίʔυ do { try getTable(length: length)?.forEach({ if memcmp($0.unescapingCodes, unichars, length)
== 0 { throw MyError.notErrorMatchedUnicode(code: $0.code) } }) throw MyError.invalidEscapeSquence } catch MyError.notErrorMatchedUnicode(let code) { return code } forEachɼྫ֎Ͱൈ͚ΒΕΔ errorͷܕʹΓΛຒΊࠐΜͰ͓͚Λड͚औΕΔ
16ਐ๏ͷจࣈྻΛUTF16ίʔυʹม B Y ' #
$ B T Y Y Y Y Y Y Y Y Y Y Y Y Y Y 128700 = 1 x 65536 + 15 x 4096 + 6 x 256 + 11x16 + 12 ݩͷจࣈྻ unicharͷྻ ίʔυ
16ਐͷ߹ // 16ਐͷจࣈྻ͔ΒΛ࡞Δ let utf16: UInt = try utf16Storage.reduce(0) {
switch $1 { case 48...57: return UInt($0) << 4 + UInt($1) - 48 case 65...70: return UInt($0) << 4 + UInt($1) - 65 + 10 case 97...102: return UInt($0) << 4 + UInt($1) - 97 + 10 default: throw HTMLSpecialCharactersError.invalidHexSquence } } return [unichar(utf16)] 10ਐͷ߹ಉ༷ʹ10ഒͣͭͯͤ͠Α͍
·ͱΊΔͱ J T B N Q B J
T B Y Y Y Y Y YE Y YC Y Y String Unichar Y Y Y Y Y Y Unichar String encode matching&replace decode ಉ͡όοϑΝ
͜ΕͩͱΫϥογϡ͠·͢
·ʔͪΌΜ͕Ϟʔχϯά່ɻϦʔμʔʹͳΔ·Ͱݟಧ͚ΔεϨ Part76ʲʳ [ແஅసࡌېࢭ]©2ch.net ʂ
Y Y Y Y Y Y Y Y Y Y
Y Y Y Y Y Y Y%&" Y%% Y Y Y ֆจࣈʙ佛ʢ΄͚ͬʣ B Y ' " B T 1F60AΛαϩήʔτϖΞʹղ Y%&" Y%% ※Unichar16bit B B T String [Unichar] [Unichar] [Unichar] String decode
UTF16ͷ͔ΒunicharೋͭΛ࡞Δ
V V V V V Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y UTF16ͷͷϏοτίʔυ X X X X Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y unichar Ұͭ unichar ೋͭ X X X X V V V V V = - 1
ίʔυͰॻ͘ͱ let w: UInt = (scalar & 0b00000000000111110000000000000000) >> 16
- 1 let x1: UInt = (scalar & 0b00000000000000001111110000000000) >> 10 let x2: UInt = (scalar & 0b00000000000000000000001111111111) >> 0 let u1: UInt16 = UInt16((0b11011000 << 8) + (w << 6) + x1) let u2: UInt16 = UInt16(UInt(0b11011100 << 8) + x2) return [u1, u2] }
Escape • Unscapeͱൺֱͯ͠ɼͪΐͬͱେม • ͯ͢ͷจࣈΛݕࠪ͢Δඞཁ͕͋Δ • →binary treeͰݕࠪίετݮ • ͳΔ͘จࣈྻʹͤͣߴԽ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ
Binary search - 38Λݟ͚ͭΔ࣌
Binary search - 38Λݟ͚ͭΔ࣌
Binary search - 38Λݟ͚ͭΔ࣌
Binary search - 38Λݟ͚ͭΔ࣌
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) Y Y Y จࣈྻ ·ͱΊͯίϐʔ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ Y Y Y Y Y YE Y YC
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ Y Y Y Y Y YE Y YC
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ Y Y Y Y Y YE Y YC
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ Y Y Y Y Y YE Y YC Y Y ·ͱΊͯίϐʔ
Escape Y Y Y Y Y Y [Unichar] J T
B จࣈྻ Y b Y Y A Y$ Y& Y Y unescape ͖͢จࣈίʔυҰཡ [Unichar] Ξτϓοτ༻ͷόοϑΝ binary search log(n) จࣈྻ Y Y Y Y Y YE Y YC Y Y J T B N Q B decode
վߦίʔυͰΓ͚Δͱ͖ • จࣈྻΛ[Unichar]ͷίʔυʹม • [Unichar]͔Βɼ‘\n’ΛόοϑΝ͔Β୳͢ • ‘\n’Ͱғ·ΕΔ[Unichar]ͷҰ෦ΛStringʹม • ޮՌ •
ߴͰ͢ • ੲͷiOS2,3ͷࠒNSStringͷσίʔμ͕ΰϛ • 1ߦͣͭόΠφϦ͔Βಡ·ͳ͍ͱσʔλ͕શ໓ • ಛఆͷจࣈ͕͋ΔߦΛؚΉͱσίʔυʹࣦഊ • ͚Εɼಛఆͷߦ͚ͩͷࣦഊʹΓ͚ΒΕΔ
Pros. & cons. • String • จࣈྻͷൺֱ͍ - ΛݟΔ͚ͩͳͷͰ •
จࣈྻͷՃɼஔɼআ͍ • rangeOfͱ͔ɼcomponentsOfͱ͔͕͑Δ • [Unichar] • ྻΛͦͷ··ѻ͏ͷͰɼΤϥʔॲཧͱ͔େม • ྻͷ֬อͱ͔ίʔυ͕େม • ԿΛ͢ΔͷίʔσΟϯά͕େม
ൺֱ(iPhone7) FTDBQF ճ VOFTDBQF ճ ߦׂ ߦ )5.-λάআڈ :BIPPͷτοϓ 1SPQPTFE
Y Y Y Y จࣈྻͷ·· ॲཧ ※୯Ґ[msec] ※unescapeͷׅހͷNSAttributedStringΛͬͨࢀߟ
·ͱΊ • ୯७ͳจࣈྻॲཧͷߴԽ • จࣈίʔυͷੜσʔλͰॲཧ͢Δ • forEachΛ్தͰྫ֎ʹൈ͚Δ • ͳΔ͘จࣈྻʹ͠ͳ͍ •
վߦΧϯϚ۠ΓͷΓग़͠ʹ༗ޮ • ෳࡶͳॲཧఘΊͯɼਖ਼نදݱɾɾɾɾ
Ͱ࠷ۙͷσόΠε͍Αʂ