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
sonson
September 18, 2017
Programming
3
7.7k
Swiftで実装するHTML特殊文字の高速処理
iOSDC2017での発表スライドです.
sonson
September 18, 2017
Tweet
Share
More Decks by sonson
See All by sonson
計算グラフのJITコンパイラをLLVM on C++で作ろう
sonsongithub
2
570
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.4k
LLVM Tutorial 02 - わいわいswiftc
sonsongithub
1
390
LLVM Tutorial - わいわいswiftc
sonsongithub
0
300
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
First step of 3D touch
sonsongithub
0
600
Getting started with 3D Touch
sonsongithub
0
690
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
530
Other Decks in Programming
See All in Programming
Domain-Driven Design (Tutorial)
hschwentner
13
22k
複数のAWSアカウントから横断で 利用する Lambda Authorizer の作り方
tc3jp
0
120
CDKを使ったPagerDuty連携インフラのテンプレート化
shibuya_shogo
0
110
.NET Frameworkでも汎用ホストが使いたい!
tomokusaba
0
200
Amazon Q Developer Proで効率化するAPI開発入門
seike460
PRO
0
120
Datadog DBMでなにができる? JDDUG Meetup#7
nealle
0
150
TCAを用いたAmebaのリアーキテクチャ
dazy
0
160
Jakarta EE meets AI
ivargrimstad
0
400
技術を改善し続ける
gumioji
0
120
Learning Kotlin with detekt
inouehi
1
140
AIの力でお手軽Chrome拡張機能作り
taiseiue
0
190
15分で学ぶDuckDBの可愛い使い方 DuckDBの最近の更新
notrogue
3
520
Featured
See All Featured
Designing Experiences People Love
moore
140
23k
Scaling GitHub
holman
459
140k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
49k
Imperfection Machines: The Place of Print at Facebook
scottboms
267
13k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
193
16k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
129
19k
Building a Scalable Design System with Sketch
lauravandoore
461
33k
Optimising Largest Contentful Paint
csswizardry
34
3.1k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.2k
Navigating Team Friction
lara
183
15k
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Λ్தͰྫ֎ʹൈ͚Δ • ͳΔ͘จࣈྻʹ͠ͳ͍ •
վߦΧϯϚ۠ΓͷΓग़͠ʹ༗ޮ • ෳࡶͳॲཧఘΊͯɼਖ਼نදݱɾɾɾɾ
Ͱ࠷ۙͷσόΠε͍Αʂ