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
550
LLVMでHalideみたいな計算グラフ+JITを作りたい
sonsongithub
0
1.4k
LLVM Tutorial 02 - わいわいswiftc
sonsongithub
1
380
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
680
SSLって必要ですか〜Let's Encryptを試してみよう
sonsongithub
3
530
Other Decks in Programming
See All in Programming
ecspresso, ecschedule, lambroll を PipeCDプラグインとして動かしてみた (プロトタイプ) / Running ecspresso, ecschedule, and lambroll as PipeCD Plugins (prototype)
tkikuc
2
1.9k
Внедряем бюджетирование, или Как сделать хорошо?
lamodatech
0
950
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.2k
いりゃあせ、PHPカンファレンス名古屋2025 / Welcome to PHP Conference Nagoya 2025
ttskch
1
180
ある日突然あなたが管理しているサーバーにDDoSが来たらどうなるでしょう?知ってるようで何も知らなかったDDoS攻撃と対策 #phpcon.2024
akase244
2
7.7k
PHPで学ぶプログラミングの教訓 / Lessons in Programming Learned through PHP
nrslib
4
1.1k
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
420
Оптимизируем производительность блока Казначейство
lamodatech
0
960
2025.01.17_Sansan × DMM.swift
riofujimon
2
560
functionalなアプローチで動的要素を排除する
ryopeko
1
210
DevFest - Serverless 101 with Google Cloud Functions
tunmise
0
140
return文におけるstd::moveについて
onihusube
1
1.4k
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
96
5.3k
Designing for Performance
lara
604
68k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
3
360
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
173
51k
Music & Morning Musume
bryan
46
6.3k
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Documentation Writing (for coders)
carmenintech
67
4.5k
Building a Scalable Design System with Sketch
lauravandoore
460
33k
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Λ్தͰྫ֎ʹൈ͚Δ • ͳΔ͘จࣈྻʹ͠ͳ͍ •
վߦΧϯϚ۠ΓͷΓग़͠ʹ༗ޮ • ෳࡶͳॲཧఘΊͯɼਖ਼نදݱɾɾɾɾ
Ͱ࠷ۙͷσόΠε͍Αʂ