300 Views
October 27, 16
スライド概要
Swift 3 の変化のひとつに Foundation での NS プレフィックス削除があります。その中でも、とりわけ "新しい値型" の新設に伴って、値型とクラス型をブリッジする選択が取られた型の、そのパフォーマンスの最適化に注目してみました。
※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,693 でした。
正統派趣味人プログラマー。プログラミングとは幼馴染です。
/41SFGJY֎ $PQZ0O8SJUF ؔϞόΠϧΞϓϦڀݚձ ʜ &;/&5۽୩༑ IUUQF[OFUKQ 4XJGU
۽୩༑ 5PNPIJSP,VNBHBJ ⾣ 4XJGU͕ޠݴେ͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษڧձ͕େ͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ͍͖͍͑ͯͨɻ !FT@LVNBHBJ UPNPIJSPLVNBHBJ $PEF1JFDFGPSNBD04 IUUQF[OFUKQ 9DPEFపఈղઆ
ษڧձΛ։࠵͍ͯ͠·͢ɻ Θ͍Θ͍ɺָ͘͠ɺ ΈΜͳͰޠΒ͑ΔॴΛࢦͯ͠ ԣJ1IPOF։ൃऀษڧձ ୈճ݄ͷ։࠵ ΧδϡΞϧ4XJGUษڧձ ୈճΛ݄ʹ։࠵ʢݕ౼தʣ ΈΜͳͰ4XJGU ෮शձ ୈճΛ݄தʹ։࠵ʢݕ౼தʣ ZJEFW ˏԣɾഅंಓ IUUQTBUOEPSHHSPVQTZJEFW DTXJGU !ԣɾ੨༿ IUUQTBUOEPSHHSPVQTDTXJGU NJOOB@EF@TXJGU ˏौ୩ IUUQDTXJGUDPOOQBTTDPN
NPPLNPPLSBEJP Ќ൛ ϜοΫϜοΫϥδΦ ۽୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ͔Β ௌ͑ͯ͘͜ΔʹࣖΛָ͚ͯ͠ΉϥδΦ ຖ݄ୈ̎ɾୈ̐ ݄༵ ʹ৴ IUUQNPPLNPPLSBEJPDPNB ⾣ ୈ̒ ʢ݄ʹ৴༧ఆʣ ⾣ ୈ̑ ʰΞΫηείϯτϩʔϧʱ ⾣ ୈ̐ ʰίϝϯτͷଓ͖ˍܕʱ ⾣ ୈ̏ ʰίϝϯτʱ ⾣ ୈ̎ ʰྻܕڍʱ
%SPQ/41SFGJY JO4XJGU'PVOEBUJPO
%SPQ/41SFpYJO4XJGU'PVOEBUJPO /41SFpY ⾣ ফ͑Ώ͘ͷ ⾣ Δͷ ⾣ ڞଘ͢Δͷ
/41SFpY ڞଘ͢Δͷ ⾣ ܕ૬ͷΫϥεͰɺ৽͕ܕઃ͞Εͨͷ ⾣ /4͖ͷΫϥεͱܕɺ/4ͳ͠ͷڞ͕ͱܕଘ ͨͱ͑ʜ • NSString, String • NSData, Data • NSArray, Array<Element>
/FX7BMVF5ZQFT JO4XJGU'PVOEBUJPO
/FX7BMVF5ZQFT ʹܕ૬͢ΔΫϥεʹண ⾣ ಉͷܕΛɺߏମͰ ৽ نՃʜ/41SFpYͳ͠ ⾣ طଘͷΫϥεܕɺͦͷ·· ଘଓ ʜ/41SFpY͋Γ ⾣ ͱܕΫϥεܕΛ૬ ʹޓϒϦοδ ⾣ ܕΛओମʹѻ͏͜ͱͰɺ4XJGUͷྑ͞Λಋग़ ⾣ ͱܕΫϥεͰܕɺػೳ͕ҟͳΔ߹͋Δ
/FX7BMVF5ZQFT *NNVUBCMF⁶/4*NNVUBCMF ⾣ ಉͷߏମΛ'PVOEBUJPOʹՃ ⾣ ํͱɺੑ࣭WBSMFU*NNVUBCMFѻ͍ TUSVDU66*% DMBTT/466*%
/FX7BMVF5ZQFT .VUBCMF⁶/4.VUBCMF ⾣ ಉͷߏମΛ'PVOEBUJPOʹՃ ⾣ Ͱܕɺੑ࣭͕WBS͔MFU͔ͰมԽ TUSVDU"⒏OF5SBOTGPSN DMBTT/4"⒏OF5SBOTGPSN TUSVDU%BUF DMBTT/4%BUF TUSVDU%BUF$PNQPOFOUT DMBTT/4%BUF$PNQPOFOUT TUSVDU1FSTPO/BNF$PNQPOFOUT DMBTT/41FSTPO/BNF$PNQPOFOUT TUSVDU63- DMBTT/463- TUSVDU63-$PNQPOFOUT DMBTT/463-$PNQPOFOUT
/FX7BMVF5ZQFT .VUBCMF⁶/4*NNVUBCMF ⾣ ಉͷߏମΛ'PVOEBUJPOʹՃ ⾣ ͚ͩܕNVUBUJOHͳੑ࣭Λ࣋ͭ TUSVDU*OEFY1BUI DMBTT/4*OEFY1BUI TUSVDU/PUJpDBUJPO DMBTT/4/PUJpDBUJPO TUSVDU63-2VFSZ*UFN DMBTT/463-2VFSZ*UFN
/FX7BMVF5ZQFT .VUBCMF⁶/4 *NNVUBCMF .VUBCMF ⾣ ܕͷߏମΛ'PVOEBUJPOʹՃ ⾣ *ͱܕNNVUBCMFΛϒϦοδɺΫϥεؒΩϟετ TUSVDU$IBSBDUFS4FU DMBTT/4$IBSBDUFS4FU DMBTT/4.VUBCMF$IBSBDUFS4FU TUSVDU%BUB DMBTT/4%BUB DMBTT/4.VUBCMF%BUB TUSVDU*OEFY4FU DMBTT/4*OEFY4FU DMBTT/4.VUBCMF*OEFY4FU
7BMVF5ZQFT
7BMVF5ZQFT ࢀͱܕরܕ ⾣ ܕʜσʔλΛίϐʔ ⾣ ࢀর ܕʜΠϯελϯεΛڞ༗
ࠓ·ͰࢀরͨͬͩܕͷΛ ͯ͠ʹܕɺॏ͘ͳΒͳ͍ͷʁ
0QUJNJ[BUJPO
0QUJNJ[BUJPO 3FGFSFODF$POWFSUJCMF ⾣ ͲͷࢀরʹܕϒϦοδͰ͖Δ͔Λදݱ ⾣ ϒϦοδରͷࢀরܕlίϐʔՄೳzͱنఆ // 要所だけ抜粋 protocol ReferenceConvertible : _ObjectiveCBridgeable { // 参照型は Objective-C 互換で、コピー可能 associatedtype ReferenceType : NSObject, NSCopying }
-BSHFS7BMVF5ZQFT
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT $PQZ0O8SJUF ⾣ ΫϥεΠϯελϯεͷࢀরΛแ͠ɺڞ༗ ⾣ ॻ͖ࠐΈ࣌ʹॳΊͯɺσʔλΛෳ 8SJUF Ϋϥε Ϋϥε #SJEHF ʷ ࣮ମ ࣮ମ $PQZ
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT $PQZ0O8SJUFͷಛ ⾣ ίϐʔͷݪଇΛӡ༻ͰΧόʔʢ҉తʣ ⾣ ඞཁʹͳΔ·ͰɺσʔλͷෳίετΛճආ ⾣ ࢀরΧϯτपΓͷཧίετ૿Ճ
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT -BSHFS7BMVF5ZQFT $IBSBDUFS4FU %BUF$PNQPOFOUT %BUB *OEFY4FU *OEFY1BUI 1FSTPO/BNF$PNQPOFOUT 63- 63-$PNQPOFOUT 63-2VFSZ*UFN 66*%
%BUBͷ࣮ࡍ
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍ ⾣ /4%BUBͷϒϦοδΛఆ ⾣ ࢀরΛ@4XJGU/4%BUBͰ#PYJOH public struct Data : ReferenceConvertible, _MutablePairBoxing { // NSData とのブリッジ public typealias ReferenceType = NSData // 参照をラップ (Boxing) する internal var _wrapped : _SwiftNSData
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍ#PYJOH
⾣ /4%BUBͱ/4.VUBCMF%BUBΛ۠ผͯ͠ཧ
⾣ /4%BUBͱϝϞϦϨϕϧͰޓੑ͕͋ΔΒ͍͠
internal final class _SwiftNSData {
// NSData と NSMutableData とを管理するラッパー
var __wrapped : _MutableUnmanagedWrapper<
NSData, NSMutableData>
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍ#PYJOHৄࡉ
⾣ *NNVUBCMF·ͨ.VUBCMFͷͲͪΒ͔
⾣ /PO"3$ͰࢀরΛཧ
internal enum _MutableUnmanagedWrapper<
ImmutableType, MutableType> {
case Immutable(Unmanaged<ImmutableType>)
case Mutable(Unmanaged<MutableType>)
}
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍΠϯελϯεԽ ⾣ ෦σʔλΛɺΫϥεܕͷࢀরͰ࣋ͭ ⾣ Ұൠʹɺ*NNVUBCMFͳΠϯελϯεͰੜ public init(bytes: UnsafeRawPointer, count: Int) { _wrapped = _SwiftNSData(immutableObject: NSData(bytes: bytes, length: count)) }
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍฤू ⾣ *NNVUBCMFͳΒɺແ݅ͰNVUBCMF$PQZ ⾣ .VUBCMFͳΒɺඇ6OJRVF࣌ͷΈNVUBCMF$PQZ public mutating func append(_ other: Data) { // ここで mutableCopy の必要性を判断・実施 _applyUnmanagedMutation { $0.append(other) } }
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍॻ͖ࠐΈେલఏͷੜ ⾣ ෦σʔλΛɺଈ࠲ʹ.VUBCMFͰੜ͢Δ͜ͱ ⾣ ॳճॻࠐ࣌ͷNVUBCMF$PQZΛݮ public init(capacity: Int) { if let d = NSMutableData(capacity: capacity) { _wrapped = _SwiftNSData(mutableObject: d) } else { } } fatalError("Unable to allocate data of the requested capacity")
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT
%BUBͷ࣮ࡍࢀরܕͷม
⾣ 4XJGU/4%BUBͰอ࣋ͨ͠ࢀরΛ੍ڧΩϟετ
⾣ ڍͳີݫಈ௫Ίͣʜߴಈ࡞ʹظ
public func _bridgeToObjectiveC() -> NSData {
// NSData.self は 8 Byte
return unsafeBitCast(_wrapped, to: NSData.self)
}
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍࢀর͔ܕΒͷม ⾣ ࢀর͔ܕΒͷมɺܕͷΠχγϟϥΠβʔͰ ⾣ /4.VUBCMF%BUBʹඋ͑DPQZΛऔಘͯ͠#PYJOH public static func _forceBridgeFromObjectiveC( _ input: NSData, result: inout Data?) { result = Data(referencing: input) } public init(referencing reference: NSData) { _wrapped = _SwiftNSData(immutableObject: reference.copy() as AnyObject) }
4NBMM7BMVF5ZQFT
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT $PQZ*NNFEJBUFMZ ⾣ ߏମͷσʔλͱͯ࣋ͪ͠ɺϒϦοδ࣌ʹଈෳ ⾣ ͦͷޙɺผมೖ͢ΔͨͼʹσʔλΛෳ 8SJUF Ϋϥε σʔλ #SJEHF $PQZ ࣮ମ σʔλ
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT ଈ࣌ίϐʔͷಛ ⾣ ίϐʔͷݪଇʹ࣮ ⾣ ೖϒϦοδͰɺσʔλͷෳίετ͕ൃੜ ⾣ ࢀরΧϯτपΓͷཧίετͷআ
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT 4NBMM7BMVF5ZQFT "⒏OF5SBOTGPSN %BUF /PUJpDBUJPO
%BUFͷ࣮ࡍ
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍ ⾣ /4%BUFͷϒϦοδΛఆ ⾣ /4%BUFͷࢀর࣋ͨͣɺσʔλΛอ࣋ public struct Date : ReferenceConvertible { // NSDate とのブリッジ public typealias ReferenceType = NSDate // データを TimeInterval (Double) で直接保持 fileprivate var _time : TimeInterval
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍΠϯελϯεԽ ⾣ ෦σʔλΛɺσʔλͱͯ࣋ͭ͠ ⾣ /4%BUFؔ༩͠ͳ͍ public init(timeIntervalSinceReferenceDate ti: TimeInterval) { _time = ti }
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍฤू ⾣ ෦σʔλΛॻ͖͑Δ ⾣ ࣗઐ༻ͷσʔλͳͷͰɺࢀরͳͲߟྀෆཁ public mutating func addTimeInterval( _ timeInterval: TimeInterval) { self += timeInterval }
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍࢀরܕͷϒϦοδ ⾣ ෦σʔλ͔Β/4%BUBΛੜ ⾣ ૉ͔ͭ࠷ͰڑͷϒϦοδ public func _bridgeToObjectiveC() -> NSDate { return NSDate(timeIntervalSinceReferenceDate: _time) }
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT
%BUFͷ࣮ࡍࢀর͔ܕΒͷϒϦοδ
⾣ /4%BUBͷ֘ใ͔ΒΠϯελϯεΛੜ
⾣ ࢀরཧ͔ΒಠཱʢࢀরΧϯτΛڞ༗͠ͳ͍ʣ
public
static func _conditionallyBridgeFromObjectiveC(
_ x: NSDate, result: inout Date?) -> Bool {
result = Date(timeIntervalSinceReferenceDate:
x.timeIntervalSinceReferenceDate)
return true
}
Ͱܕɺ ύϑΥʔϚϯεΛͨ͠ʹؾઃܭ
/FX7BMVF5ZQFT ҆৺ͯͬͯ͠ɺେৎͦ͏ɻ
&OKPZ4XJGU 5IBOLZPV /41SFpY֎ $PQZ0O8SJUF &;/&5۽୩༑ IUUQF[OFUKQ ⾣ /FX7BMVF5ZQFT ⾣ 0QUJNJ[BUJPO ⾣ %BUBͷ࣮ࡍɺ%BUFͷ࣮ࡍ