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.8k
Swiftで実装するHTML特殊文字の高速処理
iOSDC2017での発表スライドです.
sonson
September 18, 2017
Tweet
Share
More Decks by sonson
See All by sonson
計算グラフのJITコンパイラをLLVM on C++で作ろう
sonsongithub
2
580
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.5k
LLVM Tutorial 02 - わいわいswiftc
sonsongithub
1
420
LLVM Tutorial - わいわいswiftc
sonsongithub
0
320
How to make and publish a Swift playground book for iPad
sonsongithub
5
19k
First step of 3D touch
sonsongithub
0
630
Getting started with 3D Touch
sonsongithub
0
720
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
560
Other Decks in Programming
See All in Programming
Code as Context 〜 1にコードで 2にリンタ 34がなくて 5にルール? 〜
yodakeisuke
0
120
初学者でも今すぐできる、Claude Codeの生産性を10倍上げるTips
s4yuba
16
11k
PostgreSQLのRow Level SecurityをPHPのORMで扱う Eloquent vs Doctrine #phpcon #track2
77web
2
510
Deep Dive into ~/.claude/projects
hiragram
13
2.5k
Flutterで備える!Accessibility Nutrition Labels完全ガイド
yuukiw00w
0
160
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
720
猫と暮らす Google Nest Cam生活🐈 / WebRTC with Google Nest Cam
yutailang0119
0
110
設計やレビューに悩んでいるPHPerに贈る、クリーンなオブジェクト設計の指針たち
panda_program
6
1.9k
Goで作る、開発・CI環境
sin392
0
220
iOS 26にアップデートすると実機でのHot Reloadができない?
umigishiaoi
0
120
Hack Claude Code with Claude Code
choplin
0
380
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
50
33k
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
The Cult of Friendly URLs
andyhume
79
6.5k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Why Our Code Smells
bkeepers
PRO
337
57k
Facilitating Awesome Meetings
lara
54
6.4k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.6k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
For a Future-Friendly Web
brad_frost
179
9.8k
Building an army of robots
kneath
306
45k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.5k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
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Λ్தͰྫ֎ʹൈ͚Δ • ͳΔ͘จࣈྻʹ͠ͳ͍ •
վߦΧϯϚ۠ΓͷΓग़͠ʹ༗ޮ • ෳࡶͳॲཧఘΊͯɼਖ਼نදݱɾɾɾɾ
Ͱ࠷ۙͷσόΠε͍Αʂ