NS Prefix 外伝 … Copy-On-Write #関モバ

300 Views

October 27, 16

スライド概要

Swift 3 の変化のひとつに Foundation での NS プレフィックス削除があります。その中でも、とりわけ "新しい値型" の新設に伴って、値型とクラス型をブリッジする選択が取られた型の、そのパフォーマンスの最適化に注目してみました。

※ Docswell での公開に移行する直前の Slideshare での閲覧数は 3,693 でした。

profile-image

正統派趣味人プログラマー。プログラミングとは幼馴染です。

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

ダウンロード

関連スライド

各ページのテキスト
1.

/41SFGJY֎఻ $PQZ0O8SJUF ؔ੢ϞόΠϧΞϓϦ‫ڀݚ‬ձ ʜ &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ 4XJGU

2.

‫۽‬୩༑޺ 5PNPIJSP,VNBHBJ ⾣ 4XJGU‫͕ޠݴ‬௒େ޷͖Ͱ͢ʂ ⾣ ΈΜͳͰָ͠Ήษ‫ڧ‬ձ͕େ޷͖Ͱ͢ʂ ⾣ ϓϩάϥϛϯάͷָ͠͞Λ఻͍͖͍͑ͯͨɻ !FT@LVNBHBJ UPNPIJSPLVNBHBJ $PEF1JFDFGPSNBD04 IUUQF[OFUKQ 9DPEFపఈղઆ

3.

ษ‫ڧ‬ձΛ։࠵͍ͯ͠·͢ɻ Θ͍Θ͍ɺָ͘͠ɺ ΈΜͳͰ‫ޠ‬Β͑Δ৔ॴΛ໨ࢦͯ͠ ԣ඿J1IPOF։ൃऀษ‫ڧ‬ձ ୈճ໨͸݄೔ͷ։࠵ ΧδϡΞϧ4XJGUษ‫ڧ‬ձ ୈճ໨Λ݄ʹ։࠵ʢ‫ݕ‬౼தʣ ΈΜͳͰ4XJGU ෮शձ ୈճ໨Λ݄தʹ։࠵ʢ‫ݕ‬౼தʣ ZJEFW ˏԣ඿ɾഅंಓ IUUQTBUOEPSHHSPVQTZJEFW DTXJGU !ԣ඿ɾ੨༿୆ IUUQTBUOEPSHHSPVQTDTXJGU NJOOB@EF@TXJGU ˏौ୩ IUUQDTXJGUDPOOQBTTDPN

4.

NPPLNPPLSBEJP Ќ൛ ϜοΫϜοΫϥδΦ ‫۽‬୩ͱ៸໘͕ϓϩάϥϛϯάίʔυͷ಺͔Β ௌ͑ͯ͘͜Δ੠ʹࣖΛ܏ָ͚ͯ͠ΉϥδΦ ຖ݄ୈ̎ɾୈ̐ ݄༵೔ ʹ഑৴ IUUQNPPLNPPLSBEJPDPNB ⾣ ୈ̒࿩ ʢ݄೔ʹ഑৴༧ఆʣ ⾣ ୈ̑࿩ ʰΞΫηείϯτϩʔϧʱ ⾣ ୈ̐࿩ ʰίϝϯτͷଓ͖ˍ੔਺‫ܕ‬ʱ ⾣ ୈ̏࿩ ʰίϝϯτʱ ⾣ ୈ̎࿩ ʰྻ‫ܕڍ‬ʱ

5.

%SPQ/41SFGJY JO4XJGU'PVOEBUJPO

6.

%SPQ/41SFpYJO4XJGU'PVOEBUJPO /41SFpY ⾣ ফ͑Ώ͘΋ͷ ⾣ ࢒Δ΋ͷ ⾣ ‫ڞ‬ଘ͢Δ΋ͷ

7.

/41SFpY ‫ڞ‬ଘ͢Δ΋ͷ ⾣ ஋‫ܕ‬૬౰ͷΫϥεͰɺ஋‫৽͕ܕ‬ઃ͞Εͨ΋ͷ ⾣ /4෇͖ͷΫϥε‫ͱܕ‬ɺ/4ͳ͠ͷ஋‫ڞ͕ͱܕ‬ଘ ͨͱ͑͹ʜ • NSString, String • NSData, Data • NSArray, Array<Element>

8.

/FX7BMVF5ZQFT JO4XJGU'PVOEBUJPO

9.

/FX7BMVF5ZQFT ஋‫ʹܕ‬૬౰͢ΔΫϥεʹண໨ ⾣ ಉ౳ͷ஋‫ܕ‬Λɺߏ଄ମͰ ৽‫ ن‬௥Ճʜ/41SFpYͳ͠ ⾣ ‫ط‬ଘͷΫϥε‫ܕ‬͸ɺͦͷ·· ଘଓ ʜ/41SFpY͋Γ ⾣ ஋‫ͱܕ‬Ϋϥε‫ܕ‬Λ૬‫ ʹޓ‬ϒϦοδ ⾣ ஋‫ܕ‬Λओମʹѻ͏͜ͱͰɺ4XJGUͷྑ͞Λಋग़ ⾣ ஋‫ͱܕ‬Ϋϥε‫Ͱܕ‬ɺ‫ػ‬ೳ͕΍΍ҟͳΔ৔߹΋͋Δ

10.

/FX7BMVF5ZQFT *NNVUBCMF⁶/4*NNVUBCMF ⾣ ಉ౳ͷߏ଄ମΛ'PVOEBUJPOʹ௥Ճ ⾣ ૒ํͱ΋ɺੑ࣭͸WBS΋MFU΋*NNVUBCMFѻ͍ TUSVDU66*% DMBTT/466*%

11.

/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

12.

/FX7BMVF5ZQFT .VUBCMF⁶/4*NNVUBCMF ⾣ ಉ౳ͷߏ଄ମΛ'PVOEBUJPOʹ௥Ճ ⾣ ஋‫͚ͩܕ‬NVUBUJOHͳੑ࣭Λ࣋ͭ TUSVDU*OEFY1BUI DMBTT/4*OEFY1BUI TUSVDU/PUJpDBUJPO DMBTT/4/PUJpDBUJPO TUSVDU63-2VFSZ*UFN DMBTT/463-2VFSZ*UFN

13.

/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

14.

7BMVF5ZQFT

15.

7BMVF5ZQFT ஋‫ࢀͱܕ‬র‫ܕ‬ ⾣ ஋‫  ܕ‬ʜσʔλΛίϐʔ ⾣ ࢀর‫ ܕ‬ʜΠϯελϯεΛ‫ڞ‬༗

16.

ࠓ·Ͱࢀর‫ͨͬͩܕ‬ͷΛ ஋‫ͯ͠ʹܕ‬ɺॏ͘ͳΒͳ͍ͷʁ

17.

0QUJNJ[BUJPO

18.

0QUJNJ[BUJPO 3FGFSFODF$POWFSUJCMF ⾣ Ͳͷࢀর‫ʹܕ‬ϒϦοδͰ͖Δ͔Λද‫ݱ‬ ⾣ ϒϦοδର৅ͷࢀর‫ܕ‬͸lίϐʔՄೳzͱ‫ن‬ఆ // 要所だけ抜粋 protocol ReferenceConvertible : _ObjectiveCBridgeable { // 参照型は Objective-C 互換で、コピー可能 associatedtype ReferenceType : NSObject, NSCopying }

19.

-BSHFS7BMVF5ZQFT

20.

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT $PQZ0O8SJUF ⾣ ΫϥεΠϯελϯεͷࢀরΛ಺แ͠ɺ‫ڞ‬༗ ⾣ ॻ͖ࠐΈ࣌ʹॳΊͯɺσʔλΛෳ੡ ஋ 8SJUF Ϋϥε Ϋϥε #SJEHF ʷ ࣮ମ ࣮ମ $PQZ

21.

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT $PQZ0O8SJUFͷಛ௃ ⾣ ίϐʔͷ‫ݪ‬ଇΛӡ༻ͰΧόʔʢ҉໧తʣ ⾣ ඞཁʹͳΔ·Ͱɺσʔλͷෳ੡ίετΛճආ ⾣ ࢀরΧ΢ϯτपΓͷ؅ཧίετ͸૿Ճ

22.

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT -BSHFS7BMVF5ZQFT  $IBSBDUFS4FU  %BUF$PNQPOFOUT  %BUB  *OEFY4FU  *OEFY1BUI  1FSTPO/BNF$PNQPOFOUT  63-  63-$PNQPOFOUT  63-2VFSZ*UFN  66*%

23.

%BUBͷ࣮ࡍ

24.

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

25.
[beta]
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT

%BUBͷ࣮ࡍ#PYJOH
⾣ /4%BUBͱ/4.VUBCMF%BUBΛ۠ผͯ͠؅ཧ
⾣ /4%BUBͱϝϞϦϨϕϧͰ‫׵ޓ‬ੑ͕͋ΔΒ͍͠

internal final class _SwiftNSData {
// NSData と NSMutableData とを管理するラッパー

var __wrapped : _MutableUnmanagedWrapper<
NSData, NSMutableData>

26.
[beta]
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT

%BUBͷ࣮ࡍ#PYJOHৄࡉ
⾣ *NNVUBCMF·ͨ͸.VUBCMFͷͲͪΒ͔
⾣ /PO"3$ͰࢀরΛ؅ཧ

internal enum _MutableUnmanagedWrapper<
ImmutableType, MutableType> {
case Immutable(Unmanaged<ImmutableType>)
case Mutable(Unmanaged<MutableType>)
}

27.

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍΠϯελϯεԽ ⾣ ಺෦σʔλΛɺΫϥε‫ܕ‬ͷࢀরͰ࣋ͭ ⾣ Ұൠʹɺ*NNVUBCMFͳΠϯελϯεͰੜ੒ public init(bytes: UnsafeRawPointer, count: Int) { _wrapped = _SwiftNSData(immutableObject: NSData(bytes: bytes, length: count)) }

28.

0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT %BUBͷ࣮ࡍฤू ⾣ *NNVUBCMFͳΒɺແ৚݅ͰNVUBCMF$PQZ ⾣ .VUBCMFͳΒɺඇ6OJRVF࣌ͷΈNVUBCMF$PQZ public mutating func append(_ other: Data) { // ここで mutableCopy の必要性を判断・実施 _applyUnmanagedMutation { $0.append(other) } }

29.

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")

30.
[beta]
0QUJNJ[BUJPOGPS-BSHFS7BMVF5ZQFT

%BUBͷ࣮ࡍࢀর‫΁ܕ‬ͷม‫׵‬
⾣ 4XJGU/4%BUBͰอ࣋ͨ͠ࢀরΛ‫੍ڧ‬Ωϟετ
⾣ ‫ڍͳີݫ‬ಈ͸௫Ίͣʜߴ଎ಈ࡞ʹ͸‫ظ‬଴

public func _bridgeToObjectiveC() -> NSData {
// NSData.self は 8 Byte

return unsafeBitCast(_wrapped, to: NSData.self)
}

31.

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) }

32.

4NBMM7BMVF5ZQFT

33.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT $PQZ*NNFEJBUFMZ ⾣ ߏ଄ମͷσʔλͱͯ࣋ͪ͠ɺϒϦοδ࣌ʹଈෳ੡ ⾣ ͦͷ‫ޙ‬΋ɺผม਺΁୅ೖ͢ΔͨͼʹσʔλΛෳ੡ ஋ 8SJUF Ϋϥε σʔλ #SJEHF $PQZ ࣮ମ σʔλ

34.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT ଈ࣌ίϐʔͷಛ௃ ⾣ ίϐʔͷ‫ݪ‬ଇʹ஧࣮ ⾣ ୅ೖ΍ϒϦοδͰɺσʔλ෼ͷෳ੡ίετ͕ൃੜ ⾣ ࢀরΧ΢ϯτपΓͷ؅ཧίετͷ࡟আ

35.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT 4NBMM7BMVF5ZQFT  "⒏OF5SBOTGPSN  %BUF  /PUJpDBUJPO

36.

%BUFͷ࣮ࡍ

37.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍ ⾣ /4%BUF΁ͷϒϦοδΛ૝ఆ ⾣ /4%BUF΁ͷࢀর͸࣋ͨͣɺσʔλΛ௚઀อ࣋ public struct Date : ReferenceConvertible { // NSDate とのブリッジ public typealias ReferenceType = NSDate // データを TimeInterval (Double) で直接保持 fileprivate var _time : TimeInterval

38.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍΠϯελϯεԽ ⾣ ಺෦σʔλΛɺσʔλͱͯ͠௚઀࣋ͭ ⾣ /4%BUF͸ؔ༩͠ͳ͍ public init(timeIntervalSinceReferenceDate ti: TimeInterval) { _time = ti }

39.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍฤू ⾣ ಺෦σʔλΛॻ͖‫͑׵‬Δ ⾣ ࣗ෼ઐ༻ͷσʔλͳͷͰɺࢀরͳͲ͸ߟྀෆཁ public mutating func addTimeInterval( _ timeInterval: TimeInterval) { self += timeInterval }

40.

0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT %BUFͷ࣮ࡍࢀর‫΁ܕ‬ͷϒϦοδ ⾣ ಺෦σʔλ͔Β/4%BUBΛੜ੒ ⾣ ૉ௚͔ͭ࠷୹‫Ͱ཭ڑ‬ͷϒϦοδ public func _bridgeToObjectiveC() -> NSDate { return NSDate(timeIntervalSinceReferenceDate: _time) }

41.
[beta]
0QUJNJ[BUJPOGPS4NBMM7BMVF5ZQFT

%BUFͷ࣮ࡍࢀর‫͔ܕ‬ΒͷϒϦοδ
⾣ /4%BUBͷ౰֘৘ใ͔ΒΠϯελϯεΛੜ੒
⾣ ࢀর؅ཧ͔ΒಠཱʢࢀরΧ΢ϯτΛ‫ڞ‬༗͠ͳ͍ʣ

public
static func _conditionallyBridgeFromObjectiveC(
_ x: NSDate, result: inout Date?) -> Bool {
result = Date(timeIntervalSinceReferenceDate:
x.timeIntervalSinceReferenceDate)
return true
}

42.

஋‫Ͱܕ‬΋ɺ ύϑΥʔϚϯεΛ‫ͨ͠ʹؾ‬ઃ‫ܭ‬

43.

/FX7BMVF5ZQFT ҆৺ͯ͠࢖ͬͯɺେৎ෉ͦ͏ɻ

44.

&OKPZ4XJGU 5IBOLZPV /41SFpY֎఻ $PQZ0O8SJUF &;/&5‫۽‬୩༑޺ IUUQF[OFUKQ ⾣ /FX7BMVF5ZQFT ⾣ 0QUJNJ[BUJPO ⾣ %BUBͷ࣮ࡍɺ%BUFͷ࣮ࡍ