SlideShare ist ein Scribd-Unternehmen logo
1 von 132
Downloaden Sie, um offline zu lesen
Swift
2016 Let'Swift
' '
Value Semantics vs. Reference Semantics
Swift Type
...
!
' , .'
,
.
.
' ' .

.
.
Value Semantics & Reference Semantics
Value Semantics
Copy-by-Value : 

(Identity) < (Equality)

Struct, Enum, Tuple Objective-C Swift Value Type
Swift class ReferenceType
ValueType
Stack 



Heap -> Reference Counting
Value Semantics & Reference Semantics
Value Type
Struct Value Type
struct SomeStruct {
var value = 10
}
func foo() {
var bar1 = SomeStruct()
var bar2 = bar1
bar2.value = 11
}
foo()
Value Semantics & Reference Semantics
Struct Value Type
struct SomeStruct {
var value = 10
}
func foo() {
var bar1 = SomeStruct()
var bar2 = bar1
bar2.value = 11
}
foo()
Value Semantics & Reference Semantics
bar2 : (7FFEEFBFF4B0) : 0B 00 00 00
00 00 00 00
bar1 : (7FFEEFBFF4B8) : 0A 00 00 00
00 00 00 00
Struct Value Type
struct SomeStruct {
var value = 10
}
func foo() {
var bar1 = SomeStruct()
var bar2 = bar1
bar2.value = 11
}
foo()
bar2 : (7FFEEFBFF4B0) : 0B 00 00 00
00 00 00 00
bar1 : (7FFEEFBFF4B8) : 0A 00 00 00
00 00 00 00!
Value Semantics & Reference Semantics
Stack 8 Byte
bar1.value // 10
bar2.value // 11
I
class SomeClass {
var value = 10
}
func foo() {
var bar1 = SomeClass()
var bar2 = bar1
bar2.value = 11
}
foo()
Value Semantics & Reference Semantics
Class Value Type
Value Semantics & Reference Semantics
Class Value Type
Stack 8 Byte
class SomeClass {
var value = 10
}
func foo() {
var bar1 = SomeClass()
var bar2 = bar1
bar2.value = 11
}
foo()
bar2 : (7FFEEFBFF4A0) : 20 FF 0A 03
01 00 00 00
bar1 : (7FFEEFBFF4A8) : 20 FF 0A 03
01 00 00 00
(1030AFF20) : 80 8F 00 00 01 00 00 00
02 00 00 00 02 00 00 00
0B 00 00 00 00 00 00 00
a
class SomeClass {
var value = 10
}
func foo() {
var bar1 = SomeClass()
var bar2 = bar1
bar2.value = 11
}
foo()
bar2 : (7FFEEFBFF4A0) : 20 FF 0A 03
01 00 00 00
bar1 : (7FFEEFBFF4A8) : 20 FF 0A 03
01 00 00 00
(1030AFF20) : 80 8F 00 00 01 00 00 00
02 00 00 00 02 00 00 00
0B 00 00 00 00 00 00 00
Value Semantics & Reference Semantics
Class Value Type
0x1030aff20
11
??
bar1.value // 11
bar2.value // 11
Identity( ) Equality( ) : 

Swift Equatable : Equality . (==)
Value Semantics & Reference Semantics
Value Semantics : ' '
, 

Thread -> Thread Safe
Value Semantics & Reference Semantics
Value Type Thread
' '(constant time)
Value Semantics & Reference Semantics
?
Value Type Heap Value Type
Int, Double String, Array, Dictionary
' '
' ' + 

Copy-on-Write : , Value Semantics
1
Struct Array .
?
Value Semantics & Reference Semantics
func foo() {
let iterationCounts = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000]
for iterationCount in iterationCounts {
print("Iteration Count : (iterationCount)")
var array = [Int]()
for number in 0 ..< iterationCount {
array.append(number)
}
var startTime = CFAbsoluteTimeGetCurrent()
let array2 = array
print(" : (CFAbsoluteTimeGetCurrent() - startTime)")
startTime = CFAbsoluteTimeGetCurrent()
var array3 = array
array[0] = 1
print(" : (CFAbsoluteTimeGetCurrent() - startTime)")
print("------------------------")
}
}
foo()
func foo() {
let iterationCounts = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000]
for iterationCount in iterationCounts {
print("Iteration Count : (iterationCount)")
var array = [Int]()
for number in 0 ..< iterationCount {
array.append(number)
}
var startTime = CFAbsoluteTimeGetCurrent()
let array2 = array
print(" : (CFAbsoluteTimeGetCurrent() - startTime)")
startTime = CFAbsoluteTimeGetCurrent()
var array3 = array
array[0] = 1
print(" : (CFAbsoluteTimeGetCurrent() - startTime)")
print("------------------------")
}
}
foo()
n
Iteration Count : 10
: 1.0728836059570312e-06
: 2.205371856689453e-05
------------------------
Iteration Count : 100
: 0.0
: 9.5367431640625e-07
------------------------
Iteration Count : 1000
: 9.5367431640625e-07
: 2.0265579223632812e-06
------------------------
Iteration Count : 10000
: 2.0265579223632812e-06
: 3.898143768310547e-05
------------------------
Iteration Count : 100000
: 3.0994415283203125e-06
: 0.0003249645233154297
------------------------
Iteration Count : 1000000
: 4.0531158447265625e-06
: 0.0033320188522338867
------------------------
Iteration Count : 10000000
: 2.9802322387695312e-06
: 0.03259694576263428
------------------------
Iteration Count : 100000000
: 2.0265579223632812e-06
: 0.34505295753479004
------------------------
1μs

2μs
2μs

0.3s
10
1
Array ' ' .

Copy-on-Write ,
.
, .

Heap Value Type , Copy-on-Write
.
f
rnr
rn
Swift Array Struct , Struct Value Type ,

Stack Heap ?
Array Heap ?
Value Semantics & Reference Semantics
func foo() {
var array = [1, 2, 3, 4, 5]
withUnsafeBytes(of: &array) { print($0) }
}
foo()
func foo() {
var array = [1, 2, 3, 4, 5]
withUnsafeBytes(of: &array) { print($0) }
}
foo()
UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8)
???
40 Byte
func foo() {
var array = [1, 2, 3, 4, 5]
withUnsafeBytes(of: &array) { print($0) }
}
foo()
UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8)
array : (7FFEEFBFF4A8) : 00 25 53 00 01 00 00 00
func foo() {
var array = [1, 2, 3, 4, 5]
withUnsafeBytes(of: &array) { print($0) }
}
foo()
UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8)
array : (7FFEEFBFF4A8) : 00 25 53 00 01 00 00 00
(100532500) : A0 19 B3 94 FF 7F 00 00
02 00 00 00 00 00 00 00
05 00 00 00 00 00 00 00
0A 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00
02 00 00 00 00 00 00 00
03 00 00 00 00 00 00 00
04 00 00 00 00 00 00 00
05 00 00 00 00 00 00 00
Heap
Array Struct Heap ,
.
Value Semantics & Reference Semantics
Reference Type Immutable ?
Value Type , Thread-Safe 

Reference Type Immutable ?
Value Semantics & Reference Semantics
Reference Type Immutable ?
Reference Type Immutable Thread 

Foundation 

(NSAttributedString <-> NSMutableAttributedString )

Immutable 

Mutable
Value Semantics & Reference Semantics
Reference Type Immutable ?
Immutable
var array = NSArray()
for number in [1, 2, 3] {
array = array.adding(number) as NSArray
}
GO
Value Semantics & Reference Semantics
Reference Type Immutable ?
Immutable
var array = NSArray()
for number in [1, 2, 3] {
array = array.adding(number) as NSArray
}
var array = NSMutableArray()
for number in [1, 2, 3] {
array.add(number)
}
i
Value Semantics & Reference Semantics
Reference Type Immutable ?
API
// Mutable API
car.dashboard.speed = 100
// Immutable API
car.dashboard = Car.Dashboard(speed: 100)
// car = Car(dashboard: Car.Dashboard(speed: 100))


TO
of
Dashboard
Value Semantics & Reference Semantics
Class .
Identity Equality 



Objective-C : Cocoa / Cocoa Touch Objective-C 

Indirect Storage : Struct
100P t
Memory Allocation Reference Counting Method Dispatch
Stack
Heap
Yes
No
Static
Dynamic
Heap 

Memory Fragmentation - 

Thread-Safe : lock -> 

Stack : ,
Heap
String 

Heap 



Value Type Heap
Heap
Heap
//
let key = "(color)(theme)(selected)"
//
enum Color {}
enum Theme {}
struct Attribute: Hashable {
var color: Color
var theme: Theme
var selected: Bool
}
let key = Attribute(color: color, theme: theme, selected: selected)
string
let L
t Dictionary Key Hashable
iii
in j
it
Reference Counting
Reference Counting
Reference Counting . Reference Type 

Reference Counting Thread-Safe , Atomic
Reference Counting
Reference Counting
class A {}
func foo(_ a: A) {}
let a0 = A()
var a1: A? = a0
foo(a0)
a1 = nil
l
Reference Counting
Reference Counting
class A {}
func foo(_ a: A) {
// retain(a) : 3
// release(a) : 2
}
let a0 = A()
// alloc(A): 1
var a1: A? = a0
// retain(a0) : 2
foo(a0)
a1 = nil
// release(a1): 1
retain release
.
Reference Counting
Reference Counting
for _ in 0 ..< 1000000 {
foo(c0)
}
retain release ->
Reference Counting
CFGetRetainCount Reference Count .

( Reference Count .)
Reference Counting
class A {
deinit { print("deinit") }
}
func foo(_ a: A?) {
print(CFGetRetainCount(a))
}
var a0: A? = A()
print(CFGetRetainCount(a0))
var a1: A? = a0
print(CFGetRetainCount(a0))
foo(a0)
print(CFGetRetainCount(a0))
a1 = nil
print(CFGetRetainCount(a0))
a0 = nil
Reference Count 

retain 1 ,

release 1 .
2
3
4
3
2
deinit
ref I
refI2
ref
refI 2
ref I print I
refiO
Strong De Ht i RC 0
child
R I
4
parentRL 2
ParentRC I
parentdeinit t RC I
Weak Optional i 1
RC I
person deinitU RC 0
Apartment tenant
t
myParent weak
RC 0 Child
Parent RC 0
4 nil
Unowned Non Optional
Weak
Customer 1 0 nil
CreditCardcustomer
nil
T
Static Method Dispatch
-> 

:
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
drawPoint(point)
drawPoint(_:)
point.draw()
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
point.draw()
draw()
print(point.x, point.y)
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
print(point.x, point.y)
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
print(point.x, point.y)
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
drawPoint(point)
drawPoint(point) print(point.x, point.y) .
e
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
print(point.x, point.y)
struct Point {
var x: CGFloat
var y: CGFloat
func draw() {
print(x, y)
}
}
func drawPoint(_ point: Point) {
point.draw()
}
let point = Point(x: 0, y: 0)
drawPoint(point)
Dynamic Method Dispatch


.
Dynamic Method Dispatch
class Drawable {
func draw() {}
}
class Point: Drawable {
var x: CGFloat
var y: CGFloat
// init...
override func draw() { ... }
}
class Line: Drawable {
var x1: CGFloat
var y1: CGFloat
var x2: CGFloat
var y2: CGFloat
// init...
override func draw() { ... }
}
func draw(_ drawable: Drawable) {
drawable.draw()
}
Dynamic Method Dispatch
class Drawable {
func draw() {}
}
class Point: Drawable {
var x: CGFloat
var y: CGFloat
// init...
override func draw() { ... }
}
class Line: Drawable {
var x1: CGFloat
var y1: CGFloat
var x2: CGFloat
var y2: CGFloat
// init...
override func draw() { ... }
}
func draw(_ drawable: Drawable) {
drawable.draw()
}
Point.draw?

Line.draw?

Drawable.draw?
Dynamic Method Dispatch


1. 

2. V-Table 

3. V-Table .

.
Dynamic Method Dispatch
Thread-Safe 

Memory Allocation 

,
Objective-C Method Dispatch
Objective-C :
// 1
[object foo:parameter];
// 2 : 1
objc_msgSend(object, @selector(foo:), parameter);
->
Static Method Dispatch
[final, private ]







[dynamic ]

[Objective-C ]

Objective-C Runtime 

[WMO(Whole Module Optimization) ]



Xcode 8
Whole-Module Optimization
Module(Swift ) 

- 

Xcode 8
Single-File Optimization
Whole-Module Optimization
final class vs. class
class final ?
final class SomeClass {
var foo = 3
func bar() {}
}
sil_vtable SomeClass {
#SomeClass.init!allocator.1: (SomeClass.Type) -> () ->
SomeClass : @$s4main9SomeClassCACycfC //
SomeClass.__allocating_init()
#SomeClass.deinit!deallocator.1: @$s4main9SomeClassCfD
// SomeClass.__deallocating_deinit
}
class SomeClass {
var foo = 3
func bar() {}
}
class DerivedSomeClass: SomeClass {}
sil_vtable SomeClass {
#SomeClass.foo!getter.1: (SomeClass) -> () ->
Int : @$s4main9SomeClassC3fooSivg //
SomeClass.foo.getter
#SomeClass.foo!setter.1: (SomeClass) -> (Int)
-> () : @$s4main9SomeClassC3fooSivs //
SomeClass.foo.setter
#SomeClass.foo!modify.1: (SomeClass) -> () ->
() : @$s4main9SomeClassC3fooSivM//
SomeClass.foo.modify
#SomeClass.bar!1: (SomeClass) -> () -> () :
@$s4main9SomeClassC3baryyF // SomeClass.bar()
#SomeClass.init!allocator.1: (SomeClass.Type)
-> () -> SomeClass : @$s4main9SomeClassCACycfC
// SomeClass.__allocating_init()
#SomeClass.deinit!deallocator.1:
@$s4main9SomeClassCfD //
SomeClass.__deallocating_deinit
}
alerts
class SomeClass {
var foo = 3
func bar() {}
}
class DerivedSomeClass: SomeClass {}
sil_vtable DerivedSomeClass {
#SomeClass.foo!getter.1: (SomeClass) -> () -> Int
: @$s4main9SomeClassC3fooSivg [inherited] //
SomeClass.foo.getter
#SomeClass.foo!setter.1: (SomeClass) -> (Int) ->
() : @$s4main9SomeClassC3fooSivs [inherited] //
SomeClass.foo.setter
#SomeClass.foo!modify.1: (SomeClass) -> () ->
() : @$s4main9SomeClassC3fooSivM [inherited] //
SomeClass.foo.modify
#SomeClass.bar!1: (SomeClass) -> () -> () :
@$s4main9SomeClassC3baryyF [inherited]//
SomeClass.bar()
#SomeClass.init!allocator.1: (SomeClass.Type) ->
() -> SomeClass : @$s4main16DerivedSomeClassCACycfC
[override] // DerivedSomeClass.__allocating_init()
#DerivedSomeClass.deinit!deallocator.1:
@$s4main16DerivedSomeClassCfD //
DerivedSomeClass.__deallocating_deinit
}
i
V-Table , final class V-Table
, class V-Table .

var stored property getter, setter, modify
, final class V-Table
.
.
final method vs. normal method
final ?
class SomeClass {
final func foo() {}
}
sil_vtable SomeClass {
#SomeClass.init!allocator.1:
(SomeClass.Type) -> () -> SomeClass :
@$s4main9SomeClassCACycfC //
SomeClass.__allocating_init()
#SomeClass.deinit!deallocator.1:
@$s4main9SomeClassCfD//
SomeClass.__deallocating_deinit
}
fool
sil_vtable SomeClass {
#SomeClass.foo!1: (SomeClass) -> () ->
() : @$s4main9SomeClassC3fooyyF //
SomeClass.foo()
#SomeClass.init!allocator.1:
(SomeClass.Type) -> () -> SomeClass :
@$s4main9SomeClassCACycfC //
SomeClass.__allocating_init()
#SomeClass.deinit!deallocator.1:
@$s4main9SomeClassCfD//
SomeClass.__deallocating_deinit
}
class SomeClass {
func foo() {}
}
V-Table , final
V-Table ,
V-Table .
.
Memory Allocation Reference Counting Method Dispatch
Stack
Heap
Yes
No
Static
Dynamic
Memory Allocation
Heap Stack 

Heap Thread-Safe
Reference Counting


Thread-Safe , Atomic
Method Dispatch
Swift
Class
Class
Memory Allocation Heap
Reference Counting Yes
Method Dispatch Dynamic (V-Table)
Reference Semantics
Swift
Class
Final Class
Memory Allocation Heap
Reference Counting Yes
Method Dispatch Static
Swift
Struct
Reference Type Struct
Memory Allocation Stack
Reference Counting No
Method Dispatch Static
Swift
Struct
Reference Type Struct
Memory Allocation Stack
Reference Counting
Yes 

(Reference Type )
Method Dispatch Static
Swift
Struct
Reference Type Struct
struct Label {
var text: String
var font: UIFont
}
// 1
let font = UIFont.systemFont(ofSize: 15)
// 2
let label = Label(text: "msg", font: font)
// 3
let label2 = label
UIFont Class (Reference Type) -> Reference Counting 

String Heap -> Reference Counting
Swift
Struct
Reference Type Struct
struct Label {
var text: String
var font: UIFont
}
// 1
let font = UIFont.systemFont(ofSize: 15)
// 2
let label = Label(text: "msg", font: font)
// 3
let label2 = label
...
refCount 3
...
HeapStack
...font
text(storage)
font
text(storage)
font
...
refCount 2
...
label
label2
Swift
Struct
Reference Type
struct HTTPRequest {
var `protocol`: String
var domain: String
var path: String
var filename: String
var `extension`: String
var query: [String: String]
var httpMethod: String
var httpVersion: String
var httpHost: String
}
Swift
Struct
Reference Type
enum HTTPMethod {
case get
case post
case put
case delete
}
enum HTTPVersion {
case v1
case v2
}
struct HTTPRequest {
var urlString: String
var httpMethod: HTTPMethod
var httpVersion: HTTPVersion
var httpHost: String
}
struct HTTPRequest {
var `protocol`: String
var domain: String
var path: String
var filename: String
var `extension`: String
var query: [String: String]
var httpMethod: String
var httpVersion: String
var httpHost: String
}
Swift
Protocol
Protocol




Value Type -> Value Semantics 

Protocol-Oriented Programming
Swift
Protocol
Protocol Value Type
protocol Drawable { func draw() }
struct Point: Drawable { func draw() { ... } }
struct Line: Drawable { func draw() { ... } }
let drawables: [Drawable] = [Point(), Line()]
for drawable in drawables {
drawable.draw()
}
Swift
Protocol
Protocol Type : Memory Allocation
Reference Type (8Byte) 

Value Type Stack
Swift
Protocol
Protocol Type : Memory Allocation
protocol Drawable {}
struct Point: Drawable {
var a: Int
}
struct Line: Drawable {
var x: Int
var y: Int
}
let drawables: [Drawable] =
[Point(), Line()]
refCount
HeapStack
...
storage
drawables
a x
y
8 Byte
16 Byte
Swift
Protocol
Protocol Type : Method Dispatch
Class -> V-Table 

Protocol -> V-Table
Swift
Protocol
Existential Container
Protocol Type 

5 Word (64bit -> 1 Word == 8 Byte)

- 3 Word : Value Buffer

- 2 Word : Buffer (VWT / PWT )

Protocol Type Existential Container 

Protocol 3 Word , 

- 3 Word : Existential Container Value Buffer 

- 3 Word : Heap ,
Value Buffer
Swift
Protocol
Value Witness Table (VWT)
Existential Container / 

allocate / copy / destruct / deallocate
Swift
Protocol
Value Witness Table (VWT)
3 Word VWT 

allocate : X

copy : Existential Container 

destruct : Existential Container 

deallocate : X
Swift
Protocol
Value Witness Table (VWT)
3 Word VWT 

allocate : Heap /
Existential Container 

copy : 

destruct : 

deallocate : / Existential Container
Swift
Protocol
Protocol Witness Table (PWT)
Method Dispatch : 

Protocol PWT
Swift
Protocol
Copy
Existential Container 

3 Word
Swift
Protocol
Copy
3 Word 

Existential Container
a: 10
b: 11
-
vwt
pwt
a: 10
b: 11
-
vwt
pwt
Stack
Swift
Protocol
Copy
3 Word 

: Existential Container Heap 

: Heap 

-> Existential Container 

* Reference Counting ! Reference Count
Swift
Protocol
Copy
ref
-
-
vwt
pwt
ref
-
-
vwt
pwt
Stack
a: 10
b: 11
c: 12
d: 13
Heap
3 Word :
Swift
Protocol
Copy
ref
-
-
vwt
pwt
ref
-
-
vwt
pwt
Stack
a: 10
b: 11
c: 12
d: 13
Heap
3 Word :
a: 10
b: 11
c: 12
d: 13
Swift
Protocol
Indirect Storage
Value Type Reference Type

Value Semantics Copy-on-Write 

isKnownUniquelyReferenced(_:)
if !isKnownUniquelyReferenced(&object) {
storage = Storage(storage)
}
Swift
Protocol
Existential Container
Protocol Type 

Class 

- Heap (3 Word )

- Dynamic Method Dispatch

- Class : V-Table

- Protocol : PWT
Swift
Protocol
3 Word Protocol Type
Memory Allocation Stack (Existential Container)
Reference Counting No
Method Dispatch Dynamic (PWT)
Swift
Protocol
3 Word Protocol Type
Memory Allocation
Stack (Existential Container)

Heap
Reference Counting No
Method Dispatch Dynamic (PWT)
Swift
Protocol Type Type ?
Protocol Type Type .
protocol SomeProtocol {
var a: Int { get }
var b: Int { get }
}
struct SomeStruct: SomeProtocol {
var a: Int = 10
var b: Int = 11
}
func foo() {
var someStruct1 = SomeStruct()
var someStruct2: SomeProtocol = SomeStruct()
withUnsafeBytes(of: &someStruct1) { print($0) }
withUnsafeBytes(of: &someStruct2) { print($0) }
}
foo()
UnsafeRawBufferPointer(start: 0x00007ffeefbff4a0, count: 16)
UnsafeRawBufferPointer(start: 0x00007ffeefbff478, count: 40)
someStruct2 : (7FFEEFBFF478) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
B8 84 00 00 01 00 00 00
38 84 00 00 01 00 00 00
someStruct1 : (7FFEEFBFF4A0) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
sil_witness_table hidden SomeStruct: SomeProtocol module main {
method #SomeProtocol.a!getter.1: <Self where Self : SomeProtocol>
(Self) -> () -> Int :
@$s4main10SomeStructVAA0B8ProtocolA2aDP1aSivgTW // protocol
witness for SomeProtocol.a.getter in conformance SomeStruct
method #SomeProtocol.b!getter.1: <Self where Self : SomeProtocol>
(Self) -> () -> Int :
@$s4main10SomeStructVAA0B8ProtocolA2aDP1bSivgTW // protocol
witness for SomeProtocol.b.getter in conformance SomeStruct
}
Swift
3 Word /
.
protocol SmallProtocol {
var a: Int { get }
var b: Int { get }
var c: Int { get }
}
protocol LargeProtocol {
var a: Int { get }
var b: Int { get }
var c: Int { get }
var d: Int { get }
}
struct SmallStruct: SmallProtocol {
var a: Int = 10
var b: Int = 11
var c: Int = 12
}
struct LargeStruct: LargeProtocol {
var a: Int = 10
var b: Int = 11
var c: Int = 12
var d: Int = 13
}
func foo() {
var smallStruct: SmallProtocol = SmallStruct()
var largeStruct: LargeProtocol = LargeStruct()
withUnsafeBytes(of: &smallStruct) { print($0) }
withUnsafeBytes(of: &largeStruct) { print($0) }
}
foo()
largeStruct : (7FFEEFBFF460) : 60 D1 54 00 01 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
90 85 00 00 01 00 00 00
88 84 00 00 01 00 00 00
smallStruct : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
10 85 00 00 01 00 00 00
68 84 00 00 01 00 00 00
(10054D160) : 50 84 00 00 01 00 00 00
02 00 00 00 00 00 00 00
0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
0D 00 00 00 00 00 00 00
Swift
3 Word / Copy
Copy .
Swift
3 Word / Copy
Copy .
protocol SmallProtocol {
var a: Int { get set }
var b: Int { get set }
var c: Int { get set }
}
struct SmallStruct: SmallProtocol {
var a: Int = 10
var b: Int = 11
var c: Int = 12
}
func foo() {
var bar1: SmallProtocol = SmallStruct()
var bar2 = bar1
// breakpoint 1
bar2.a = 11
// breakpoint 2
withUnsafeBytes(of: &bar1) { print($0) }
withUnsafeBytes(of: &bar2) { print($0) }
}
foo()
3 Word Protocol Type
// breakpoint 1
bar2 : (7FFEEFBFF460) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
28 85 00 00 01 00 00 00
50 84 00 00 01 00 00 00
bar1 : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
28 85 00 00 01 00 00 00
50 84 00 00 01 00 00 00
3 Word Protocol Type
// breakpoint 2
bar2 : (7FFEEFBFF460) : 0B 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
28 85 00 00 01 00 00 00
50 84 00 00 01 00 00 00
bar1 : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
28 85 00 00 01 00 00 00
50 84 00 00 01 00 00 00
protocol LargeProtocol {
var a: Int { get set }
var b: Int { get set }
var c: Int { get set }
var d: Int { get set }
}
struct LargeStruct: LargeProtocol {
var a: Int = 10
var b: Int = 11
var c: Int = 12
var d: Int = 13
}
func foo() {
var bar1: LargeProtocol = LargeStruct()
var bar2 = bar1
// breakpoint 1
bar2.a = 11
// breakpoint 2
withUnsafeBytes(of: &bar1) { print($0) }
withUnsafeBytes(of: &bar2) { print($0) }
}
foo()
3 Word Protocol Type
// breakpoint 1
bar2 : (7FFEEFBFF460) : 90 B2 B3 03 01 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
48 85 00 00 01 00 00 00
80 84 00 00 01 00 00 00
bar1 : (7FFEEFBFF488) : 90 B2 B3 03 01 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
48 85 00 00 01 00 00 00
80 84 00 00 01 00 00 00
3 Word Protocol Type
(103B3B290) : 0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
0D 00 00 00 00 00 00 00
// breakpoint 2
bar2 : (7FFEEFBFF460) : 70 B8 B3 03 01 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
48 85 00 00 01 00 00 00
80 84 00 00 01 00 00 00
bar1 : (7FFEEFBFF488) : 90 B2 B3 03 01 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
48 85 00 00 01 00 00 00
80 84 00 00 01 00 00 00
3 Word Protocol Type
(103B3B290) : 68 84 00 00 01 00 00 00
02 00 00 00 00 00 00 00
0A 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
0D 00 00 00 00 00 00 00
(103B3B870) : 78 19 B3 94 FF 7F 00 00
02 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
0D 00 00 00 00 00 00 00
Swift
Protocol
3 Word Protocol Type vs. Indirect Storage
3 Word Protocol Type Indirect Storage
Heap 

Reference Counting : X

Copy-on-Write -> Value Semantics
Heap 

Reference Counting : O

Value Semantics
Copy-on-Write
Swift
Generics
3 Word Protocol Type vs. Indirect Storage
protocol Drawable { func draw() }
struct Point: Drawable { func draw() { ... } }
struct Line: Drawable { func draw() { ... } }
func draw<T: Drawable>(_ drawable: T) {
drawable.draw()
}
draw(Point())
draw(Line())
Generic Type T Drawable 

Existential Container 

T : 

->
Swift
Generics
3 Word Protocol Type vs. Indirect Storage
protocol Drawable { func draw() }
struct Point: Drawable { func draw() { ... } }
struct Line: Drawable { func draw() { ... } }
func draw<T: Drawable>(_ drawable: T) {
drawable.draw()
}
draw(Point())
draw(Line())
Generic Specialization

Existential Container 

->
func draw(_ point: Point) {
point.draw()
}
func draw(_ line: Line) {
line.draw()
}
draw(Point())
draw(Line())
Swift
?
.
protocol SomeProtocol {
var a: Int { get }
}
struct SomeStruct1: SomeProtocol {
var a: Int = 10
}
struct SomeStruct2: SomeProtocol {
var a: Int = 11
var b: Int = 12
}
func bar<T: SomeProtocol>(_ bar: T) {
var bar = bar
print(type(of: bar))
withUnsafeBytes(of: &bar) { print($0) }
}
func foo() {
bar(SomeStruct1())
bar(SomeStruct2())
}
foo()
SomeStruct1
UnsafeRawBufferPointer(start: 0x00007ffeefbff380, count: 8)
SomeStruct2
UnsafeRawBufferPointer(start: 0x00007ffeefbff380, count: 16)
(7FFEEFBFF380) : 0A 00 00 00 00 00 00 00
(7FFEEFBFF380) : 0B 00 00 00 00 00 00 00
0C 00 00 00 00 00 00 00
Swift
Generics
Generics (3 Word Protocol Type)
Memory Allocation Stack (Existential Container)
Reference Counting No
Method Dispatch Dynamic (PWT)
Swift
Generics
Generics (3 Word Protocol Type)
Memory Allocation
Stack (Existential Container)

Heap
Reference Counting No
Method Dispatch Dynamic (PWT)
Swift
Generics
Generics (Struct)
Memory Allocation Stack
Reference Counting No
Method Dispatch Static
Swift
Generics
Generics (Class)
Memory Allocation Heap
Reference Counting Yes
Method Dispatch Dynamic (V-Table)
Swift
Generics
(Static Polymorphism)





(Specialization)
Value Type Protocol Type 





/
Struct : Value Semantics
Class : Identity / OOP / Objective-C Compatible
Generics : Static Polymorphism
Protocol : Dynamic Polymorphism
Struct Reference Type
- Value Type 

- Reference Counting 

Protocol Type Struct
- Indirect Storage Struct 

- Mutable Copy-on-Write 

Method Dispatch : Dynamic -> Static
- final / private

- dynamic X

- Objective-C 

- WMO
.
Reference
[Swift : Value , Protocol ], , 2016.

https://academy.realm.io/kr/posts/letswift-swift-performance/

[Cocoa Internals], , 2017.

[Swift Copy-on-Write (CoW)], OAKSONG, 2018.

https://oaksong.github.io/2018/01/06/copy-on-write/

[Whole-Module Optimization in Swift 3], Erik Eckstein, 2016

https://swift.org/blog/whole-module-optimizations/

https://github.com/presto95/Study/blob/master/Swift/Whole-
Module%20Optimization.md
.

Weitere ähnliche Inhalte

Was ist angesagt?

Introduction to AspectJ
Introduction to AspectJIntroduction to AspectJ
Introduction to AspectJ
mukhtarhudaya
 

Was ist angesagt? (20)

Structured data type
Structured data typeStructured data type
Structured data type
 
Standford 2015 week9
Standford 2015 week9Standford 2015 week9
Standford 2015 week9
 
Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++Функциональный микроскоп: линзы в C++
Функциональный микроскоп: линзы в C++
 
F
FF
F
 
Standford 2015 week3: Objective-C Compatibility, Property List, Views
Standford 2015 week3: Objective-C Compatibility, Property List, ViewsStandford 2015 week3: Objective-C Compatibility, Property List, Views
Standford 2015 week3: Objective-C Compatibility, Property List, Views
 
Basic iOS Training with SWIFT - Part 2
Basic iOS Training with SWIFT - Part 2Basic iOS Training with SWIFT - Part 2
Basic iOS Training with SWIFT - Part 2
 
Introduction to AspectJ
Introduction to AspectJIntroduction to AspectJ
Introduction to AspectJ
 
input
inputinput
input
 
Blending Culture in Twitter Client
Blending Culture in Twitter ClientBlending Culture in Twitter Client
Blending Culture in Twitter Client
 
Supstat nyc subway
Supstat nyc subwaySupstat nyc subway
Supstat nyc subway
 
Scalaz 8: A Whole New Game
Scalaz 8: A Whole New GameScalaz 8: A Whole New Game
Scalaz 8: A Whole New Game
 
Oracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman KhudrujOracle (SQL), Sulieman Khudruj
Oracle (SQL), Sulieman Khudruj
 
Examenolimpiada
ExamenolimpiadaExamenolimpiada
Examenolimpiada
 
Why you should use super() though it sucks
Why you should use super() though it sucksWhy you should use super() though it sucks
Why you should use super() though it sucks
 
VC「もしかして...」Model「私たち...」「「入れ替わってるー!?」」を前前前世から防ぐ方法
VC「もしかして...」Model「私たち...」「「入れ替わってるー!?」」を前前前世から防ぐ方法VC「もしかして...」Model「私たち...」「「入れ替わってるー!?」」を前前前世から防ぐ方法
VC「もしかして...」Model「私たち...」「「入れ替わってるー!?」」を前前前世から防ぐ方法
 
4. chapter iii
4. chapter iii4. chapter iii
4. chapter iii
 
Anomalies in X-Ray Engine
Anomalies in X-Ray EngineAnomalies in X-Ray Engine
Anomalies in X-Ray Engine
 
3. chapter ii
3. chapter ii3. chapter ii
3. chapter ii
 
Composite Pattern
Composite PatternComposite Pattern
Composite Pattern
 
Better d3 charts with tdd
Better d3 charts with tddBetter d3 charts with tdd
Better d3 charts with tdd
 

Ähnlich wie Swift 성능 이해하기

The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
corehard_by
 
Intro to tsql unit 10
Intro to tsql   unit 10Intro to tsql   unit 10
Intro to tsql unit 10
Syed Asrarali
 
4. SQL in DBMS
4. SQL in DBMS4. SQL in DBMS
4. SQL in DBMS
koolkampus
 
6. Integrity and Security in DBMS
6. Integrity and Security in DBMS6. Integrity and Security in DBMS
6. Integrity and Security in DBMS
koolkampus
 
Scala Turkiye 2013-02-07 Sunumu
Scala Turkiye 2013-02-07 SunumuScala Turkiye 2013-02-07 Sunumu
Scala Turkiye 2013-02-07 Sunumu
Volkan Yazıcı
 

Ähnlich wie Swift 성능 이해하기 (20)

The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
The C++ rvalue lifetime disaster. Arno Schödl ➠ CoreHard Autumn 2019
 
1.5.recommending music with apache spark ml
1.5.recommending music with apache spark ml1.5.recommending music with apache spark ml
1.5.recommending music with apache spark ml
 
Intro to tsql unit 10
Intro to tsql   unit 10Intro to tsql   unit 10
Intro to tsql unit 10
 
Concepts of C [Module 2]
Concepts of C [Module 2]Concepts of C [Module 2]
Concepts of C [Module 2]
 
Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
 
Unit3 C
Unit3 C Unit3 C
Unit3 C
 
4. SQL in DBMS
4. SQL in DBMS4. SQL in DBMS
4. SQL in DBMS
 
Hive function-cheat-sheet
Hive function-cheat-sheetHive function-cheat-sheet
Hive function-cheat-sheet
 
6. Integrity and Security in DBMS
6. Integrity and Security in DBMS6. Integrity and Security in DBMS
6. Integrity and Security in DBMS
 
Quill vs Slick Smackdown
Quill vs Slick SmackdownQuill vs Slick Smackdown
Quill vs Slick Smackdown
 
2e data models
2e   data models2e   data models
2e data models
 
DIWE - Advanced PHP Concepts
DIWE - Advanced PHP ConceptsDIWE - Advanced PHP Concepts
DIWE - Advanced PHP Concepts
 
Unit 5 Foc
Unit 5 FocUnit 5 Foc
Unit 5 Foc
 
ANSI C REFERENCE CARD
ANSI C REFERENCE CARDANSI C REFERENCE CARD
ANSI C REFERENCE CARD
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
 
c_tutorial_2.ppt
c_tutorial_2.pptc_tutorial_2.ppt
c_tutorial_2.ppt
 
Data types
Data typesData types
Data types
 
Scala Turkiye 2013-02-07 Sunumu
Scala Turkiye 2013-02-07 SunumuScala Turkiye 2013-02-07 Sunumu
Scala Turkiye 2013-02-07 Sunumu
 
Unit04 dbms
Unit04 dbmsUnit04 dbms
Unit04 dbms
 
Python 炒股指南
Python 炒股指南 Python 炒股指南
Python 炒股指南
 

Kürzlich hochgeladen

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
ssuser89054b
 
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
Health
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
MayuraD1
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
MsecMca
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Kandungan 087776558899
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
Neometrix_Engineering_Pvt_Ltd
 

Kürzlich hochgeladen (20)

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
+97470301568>> buy weed in qatar,buy thc oil qatar,buy weed and vape oil in d...
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
 
Bridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxBridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptx
 
Hostel management system project report..pdf
Hostel management system project report..pdfHostel management system project report..pdf
Hostel management system project report..pdf
 
Thermal Engineering Unit - I & II . ppt
Thermal Engineering  Unit - I & II . pptThermal Engineering  Unit - I & II . ppt
Thermal Engineering Unit - I & II . ppt
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
 
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak HamilCara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
Cara Menggugurkan Sperma Yang Masuk Rahim Biyar Tidak Hamil
 
Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
Integrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - NeometrixIntegrated Test Rig For HTFE-25 - Neometrix
Integrated Test Rig For HTFE-25 - Neometrix
 
Double Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torqueDouble Revolving field theory-how the rotor develops torque
Double Revolving field theory-how the rotor develops torque
 
Computer Networks Basics of Network Devices
Computer Networks  Basics of Network DevicesComputer Networks  Basics of Network Devices
Computer Networks Basics of Network Devices
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
Online electricity billing project report..pdf
Online electricity billing project report..pdfOnline electricity billing project report..pdf
Online electricity billing project report..pdf
 
Online food ordering system project report.pdf
Online food ordering system project report.pdfOnline food ordering system project report.pdf
Online food ordering system project report.pdf
 
Unleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leapUnleashing the Power of the SORA AI lastest leap
Unleashing the Power of the SORA AI lastest leap
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced LoadsFEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
FEA Based Level 3 Assessment of Deformed Tanks with Fluid Induced Loads
 
Introduction to Serverless with AWS Lambda
Introduction to Serverless with AWS LambdaIntroduction to Serverless with AWS Lambda
Introduction to Serverless with AWS Lambda
 

Swift 성능 이해하기

  • 2. 2016 Let'Swift ' ' Value Semantics vs. Reference Semantics Swift Type ... !
  • 5. .
  • 6. Value Semantics & Reference Semantics Value Semantics Copy-by-Value : (Identity) < (Equality) Struct, Enum, Tuple Objective-C Swift Value Type Swift class ReferenceType ValueType
  • 7. Stack Heap -> Reference Counting Value Semantics & Reference Semantics Value Type
  • 8. Struct Value Type struct SomeStruct { var value = 10 } func foo() { var bar1 = SomeStruct() var bar2 = bar1 bar2.value = 11 } foo() Value Semantics & Reference Semantics
  • 9. Struct Value Type struct SomeStruct { var value = 10 } func foo() { var bar1 = SomeStruct() var bar2 = bar1 bar2.value = 11 } foo() Value Semantics & Reference Semantics bar2 : (7FFEEFBFF4B0) : 0B 00 00 00 00 00 00 00 bar1 : (7FFEEFBFF4B8) : 0A 00 00 00 00 00 00 00
  • 10. Struct Value Type struct SomeStruct { var value = 10 } func foo() { var bar1 = SomeStruct() var bar2 = bar1 bar2.value = 11 } foo() bar2 : (7FFEEFBFF4B0) : 0B 00 00 00 00 00 00 00 bar1 : (7FFEEFBFF4B8) : 0A 00 00 00 00 00 00 00! Value Semantics & Reference Semantics Stack 8 Byte bar1.value // 10 bar2.value // 11 I
  • 11. class SomeClass { var value = 10 } func foo() { var bar1 = SomeClass() var bar2 = bar1 bar2.value = 11 } foo() Value Semantics & Reference Semantics Class Value Type
  • 12. Value Semantics & Reference Semantics Class Value Type Stack 8 Byte class SomeClass { var value = 10 } func foo() { var bar1 = SomeClass() var bar2 = bar1 bar2.value = 11 } foo() bar2 : (7FFEEFBFF4A0) : 20 FF 0A 03 01 00 00 00 bar1 : (7FFEEFBFF4A8) : 20 FF 0A 03 01 00 00 00 (1030AFF20) : 80 8F 00 00 01 00 00 00 02 00 00 00 02 00 00 00 0B 00 00 00 00 00 00 00 a
  • 13. class SomeClass { var value = 10 } func foo() { var bar1 = SomeClass() var bar2 = bar1 bar2.value = 11 } foo() bar2 : (7FFEEFBFF4A0) : 20 FF 0A 03 01 00 00 00 bar1 : (7FFEEFBFF4A8) : 20 FF 0A 03 01 00 00 00 (1030AFF20) : 80 8F 00 00 01 00 00 00 02 00 00 00 02 00 00 00 0B 00 00 00 00 00 00 00 Value Semantics & Reference Semantics Class Value Type 0x1030aff20 11 ?? bar1.value // 11 bar2.value // 11
  • 14. Identity( ) Equality( ) : Swift Equatable : Equality . (==) Value Semantics & Reference Semantics Value Semantics : ' '
  • 15. , Thread -> Thread Safe Value Semantics & Reference Semantics Value Type Thread
  • 16. ' '(constant time) Value Semantics & Reference Semantics ? Value Type Heap Value Type Int, Double String, Array, Dictionary ' ' ' ' + Copy-on-Write : , Value Semantics 1
  • 17. Struct Array . ? Value Semantics & Reference Semantics
  • 18. func foo() { let iterationCounts = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000] for iterationCount in iterationCounts { print("Iteration Count : (iterationCount)") var array = [Int]() for number in 0 ..< iterationCount { array.append(number) } var startTime = CFAbsoluteTimeGetCurrent() let array2 = array print(" : (CFAbsoluteTimeGetCurrent() - startTime)") startTime = CFAbsoluteTimeGetCurrent() var array3 = array array[0] = 1 print(" : (CFAbsoluteTimeGetCurrent() - startTime)") print("------------------------") } } foo()
  • 19. func foo() { let iterationCounts = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000] for iterationCount in iterationCounts { print("Iteration Count : (iterationCount)") var array = [Int]() for number in 0 ..< iterationCount { array.append(number) } var startTime = CFAbsoluteTimeGetCurrent() let array2 = array print(" : (CFAbsoluteTimeGetCurrent() - startTime)") startTime = CFAbsoluteTimeGetCurrent() var array3 = array array[0] = 1 print(" : (CFAbsoluteTimeGetCurrent() - startTime)") print("------------------------") } } foo() n
  • 20. Iteration Count : 10 : 1.0728836059570312e-06 : 2.205371856689453e-05 ------------------------ Iteration Count : 100 : 0.0 : 9.5367431640625e-07 ------------------------ Iteration Count : 1000 : 9.5367431640625e-07 : 2.0265579223632812e-06 ------------------------ Iteration Count : 10000 : 2.0265579223632812e-06 : 3.898143768310547e-05 ------------------------ Iteration Count : 100000 : 3.0994415283203125e-06 : 0.0003249645233154297 ------------------------ Iteration Count : 1000000 : 4.0531158447265625e-06 : 0.0033320188522338867 ------------------------ Iteration Count : 10000000 : 2.9802322387695312e-06 : 0.03259694576263428 ------------------------ Iteration Count : 100000000 : 2.0265579223632812e-06 : 0.34505295753479004 ------------------------ 1μs 2μs 2μs 0.3s 10 1
  • 21. Array ' ' . Copy-on-Write , . , . Heap Value Type , Copy-on-Write . f rnr rn
  • 22. Swift Array Struct , Struct Value Type , Stack Heap ? Array Heap ? Value Semantics & Reference Semantics
  • 23. func foo() { var array = [1, 2, 3, 4, 5] withUnsafeBytes(of: &array) { print($0) } } foo()
  • 24. func foo() { var array = [1, 2, 3, 4, 5] withUnsafeBytes(of: &array) { print($0) } } foo() UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8) ??? 40 Byte
  • 25. func foo() { var array = [1, 2, 3, 4, 5] withUnsafeBytes(of: &array) { print($0) } } foo() UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8) array : (7FFEEFBFF4A8) : 00 25 53 00 01 00 00 00
  • 26. func foo() { var array = [1, 2, 3, 4, 5] withUnsafeBytes(of: &array) { print($0) } } foo() UnsafeRawBufferPointer(start: 0x00007ffeefbff4a8, count: 8) array : (7FFEEFBFF4A8) : 00 25 53 00 01 00 00 00 (100532500) : A0 19 B3 94 FF 7F 00 00 02 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 05 00 00 00 00 00 00 00 Heap
  • 28. Value Semantics & Reference Semantics Reference Type Immutable ? Value Type , Thread-Safe Reference Type Immutable ?
  • 29. Value Semantics & Reference Semantics Reference Type Immutable ? Reference Type Immutable Thread Foundation (NSAttributedString <-> NSMutableAttributedString ) Immutable Mutable
  • 30. Value Semantics & Reference Semantics Reference Type Immutable ? Immutable var array = NSArray() for number in [1, 2, 3] { array = array.adding(number) as NSArray } GO
  • 31. Value Semantics & Reference Semantics Reference Type Immutable ? Immutable var array = NSArray() for number in [1, 2, 3] { array = array.adding(number) as NSArray } var array = NSMutableArray() for number in [1, 2, 3] { array.add(number) } i
  • 32. Value Semantics & Reference Semantics Reference Type Immutable ? API // Mutable API car.dashboard.speed = 100 // Immutable API car.dashboard = Car.Dashboard(speed: 100) // car = Car(dashboard: Car.Dashboard(speed: 100)) TO of Dashboard
  • 33. Value Semantics & Reference Semantics Class . Identity Equality Objective-C : Cocoa / Cocoa Touch Objective-C Indirect Storage : Struct 100P t
  • 34. Memory Allocation Reference Counting Method Dispatch Stack Heap Yes No Static Dynamic
  • 35. Heap Memory Fragmentation - Thread-Safe : lock -> Stack : , Heap
  • 36. String Heap Value Type Heap Heap
  • 37. Heap // let key = "(color)(theme)(selected)" // enum Color {} enum Theme {} struct Attribute: Hashable { var color: Color var theme: Theme var selected: Bool } let key = Attribute(color: color, theme: theme, selected: selected) string let L t Dictionary Key Hashable iii in j it
  • 38. Reference Counting Reference Counting Reference Counting . Reference Type Reference Counting Thread-Safe , Atomic
  • 39. Reference Counting Reference Counting class A {} func foo(_ a: A) {} let a0 = A() var a1: A? = a0 foo(a0) a1 = nil l
  • 40. Reference Counting Reference Counting class A {} func foo(_ a: A) { // retain(a) : 3 // release(a) : 2 } let a0 = A() // alloc(A): 1 var a1: A? = a0 // retain(a0) : 2 foo(a0) a1 = nil // release(a1): 1 retain release .
  • 41. Reference Counting Reference Counting for _ in 0 ..< 1000000 { foo(c0) } retain release ->
  • 42. Reference Counting CFGetRetainCount Reference Count . ( Reference Count .)
  • 43. Reference Counting class A { deinit { print("deinit") } } func foo(_ a: A?) { print(CFGetRetainCount(a)) } var a0: A? = A() print(CFGetRetainCount(a0)) var a1: A? = a0 print(CFGetRetainCount(a0)) foo(a0) print(CFGetRetainCount(a0)) a1 = nil print(CFGetRetainCount(a0)) a0 = nil Reference Count retain 1 , release 1 . 2 3 4 3 2 deinit ref I refI2 ref refI 2 ref I print I refiO
  • 44. Strong De Ht i RC 0 child R I 4 parentRL 2 ParentRC I parentdeinit t RC I
  • 45. Weak Optional i 1 RC I person deinitU RC 0 Apartment tenant t myParent weak RC 0 Child Parent RC 0 4 nil Unowned Non Optional Weak Customer 1 0 nil CreditCardcustomer nil T
  • 47.
  • 48. struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) drawPoint(point)
  • 49. drawPoint(_:) point.draw() struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) point.draw()
  • 50. draw() print(point.x, point.y) struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) print(point.x, point.y)
  • 51. struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) print(point.x, point.y) struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) drawPoint(point) drawPoint(point) print(point.x, point.y) . e
  • 52. struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) print(point.x, point.y) struct Point { var x: CGFloat var y: CGFloat func draw() { print(x, y) } } func drawPoint(_ point: Point) { point.draw() } let point = Point(x: 0, y: 0) drawPoint(point)
  • 54. Dynamic Method Dispatch class Drawable { func draw() {} } class Point: Drawable { var x: CGFloat var y: CGFloat // init... override func draw() { ... } } class Line: Drawable { var x1: CGFloat var y1: CGFloat var x2: CGFloat var y2: CGFloat // init... override func draw() { ... } } func draw(_ drawable: Drawable) { drawable.draw() }
  • 55. Dynamic Method Dispatch class Drawable { func draw() {} } class Point: Drawable { var x: CGFloat var y: CGFloat // init... override func draw() { ... } } class Line: Drawable { var x1: CGFloat var y1: CGFloat var x2: CGFloat var y2: CGFloat // init... override func draw() { ... } } func draw(_ drawable: Drawable) { drawable.draw() } Point.draw? Line.draw? Drawable.draw?
  • 56. Dynamic Method Dispatch 1. 2. V-Table 3. V-Table . .
  • 57. Dynamic Method Dispatch Thread-Safe Memory Allocation ,
  • 58. Objective-C Method Dispatch Objective-C : // 1 [object foo:parameter]; // 2 : 1 objc_msgSend(object, @selector(foo:), parameter); ->
  • 59. Static Method Dispatch [final, private ] [dynamic ] [Objective-C ] Objective-C Runtime [WMO(Whole Module Optimization) ] Xcode 8
  • 60. Whole-Module Optimization Module(Swift ) - Xcode 8 Single-File Optimization Whole-Module Optimization
  • 61. final class vs. class class final ?
  • 62. final class SomeClass { var foo = 3 func bar() {} } sil_vtable SomeClass { #SomeClass.init!allocator.1: (SomeClass.Type) -> () -> SomeClass : @$s4main9SomeClassCACycfC // SomeClass.__allocating_init() #SomeClass.deinit!deallocator.1: @$s4main9SomeClassCfD // SomeClass.__deallocating_deinit }
  • 63. class SomeClass { var foo = 3 func bar() {} } class DerivedSomeClass: SomeClass {} sil_vtable SomeClass { #SomeClass.foo!getter.1: (SomeClass) -> () -> Int : @$s4main9SomeClassC3fooSivg // SomeClass.foo.getter #SomeClass.foo!setter.1: (SomeClass) -> (Int) -> () : @$s4main9SomeClassC3fooSivs // SomeClass.foo.setter #SomeClass.foo!modify.1: (SomeClass) -> () -> () : @$s4main9SomeClassC3fooSivM// SomeClass.foo.modify #SomeClass.bar!1: (SomeClass) -> () -> () : @$s4main9SomeClassC3baryyF // SomeClass.bar() #SomeClass.init!allocator.1: (SomeClass.Type) -> () -> SomeClass : @$s4main9SomeClassCACycfC // SomeClass.__allocating_init() #SomeClass.deinit!deallocator.1: @$s4main9SomeClassCfD // SomeClass.__deallocating_deinit } alerts
  • 64. class SomeClass { var foo = 3 func bar() {} } class DerivedSomeClass: SomeClass {} sil_vtable DerivedSomeClass { #SomeClass.foo!getter.1: (SomeClass) -> () -> Int : @$s4main9SomeClassC3fooSivg [inherited] // SomeClass.foo.getter #SomeClass.foo!setter.1: (SomeClass) -> (Int) -> () : @$s4main9SomeClassC3fooSivs [inherited] // SomeClass.foo.setter #SomeClass.foo!modify.1: (SomeClass) -> () -> () : @$s4main9SomeClassC3fooSivM [inherited] // SomeClass.foo.modify #SomeClass.bar!1: (SomeClass) -> () -> () : @$s4main9SomeClassC3baryyF [inherited]// SomeClass.bar() #SomeClass.init!allocator.1: (SomeClass.Type) -> () -> SomeClass : @$s4main16DerivedSomeClassCACycfC [override] // DerivedSomeClass.__allocating_init() #DerivedSomeClass.deinit!deallocator.1: @$s4main16DerivedSomeClassCfD // DerivedSomeClass.__deallocating_deinit } i
  • 65. V-Table , final class V-Table , class V-Table . var stored property getter, setter, modify , final class V-Table . .
  • 66. final method vs. normal method final ?
  • 67. class SomeClass { final func foo() {} } sil_vtable SomeClass { #SomeClass.init!allocator.1: (SomeClass.Type) -> () -> SomeClass : @$s4main9SomeClassCACycfC // SomeClass.__allocating_init() #SomeClass.deinit!deallocator.1: @$s4main9SomeClassCfD// SomeClass.__deallocating_deinit } fool
  • 68. sil_vtable SomeClass { #SomeClass.foo!1: (SomeClass) -> () -> () : @$s4main9SomeClassC3fooyyF // SomeClass.foo() #SomeClass.init!allocator.1: (SomeClass.Type) -> () -> SomeClass : @$s4main9SomeClassCACycfC // SomeClass.__allocating_init() #SomeClass.deinit!deallocator.1: @$s4main9SomeClassCfD// SomeClass.__deallocating_deinit } class SomeClass { func foo() {} }
  • 69. V-Table , final V-Table , V-Table . .
  • 70. Memory Allocation Reference Counting Method Dispatch Stack Heap Yes No Static Dynamic
  • 71. Memory Allocation Heap Stack Heap Thread-Safe
  • 74. Swift Class Class Memory Allocation Heap Reference Counting Yes Method Dispatch Dynamic (V-Table) Reference Semantics
  • 75. Swift Class Final Class Memory Allocation Heap Reference Counting Yes Method Dispatch Static
  • 76. Swift Struct Reference Type Struct Memory Allocation Stack Reference Counting No Method Dispatch Static
  • 77. Swift Struct Reference Type Struct Memory Allocation Stack Reference Counting Yes (Reference Type ) Method Dispatch Static
  • 78. Swift Struct Reference Type Struct struct Label { var text: String var font: UIFont } // 1 let font = UIFont.systemFont(ofSize: 15) // 2 let label = Label(text: "msg", font: font) // 3 let label2 = label UIFont Class (Reference Type) -> Reference Counting String Heap -> Reference Counting
  • 79. Swift Struct Reference Type Struct struct Label { var text: String var font: UIFont } // 1 let font = UIFont.systemFont(ofSize: 15) // 2 let label = Label(text: "msg", font: font) // 3 let label2 = label ... refCount 3 ... HeapStack ...font text(storage) font text(storage) font ... refCount 2 ... label label2
  • 80. Swift Struct Reference Type struct HTTPRequest { var `protocol`: String var domain: String var path: String var filename: String var `extension`: String var query: [String: String] var httpMethod: String var httpVersion: String var httpHost: String }
  • 81. Swift Struct Reference Type enum HTTPMethod { case get case post case put case delete } enum HTTPVersion { case v1 case v2 } struct HTTPRequest { var urlString: String var httpMethod: HTTPMethod var httpVersion: HTTPVersion var httpHost: String } struct HTTPRequest { var `protocol`: String var domain: String var path: String var filename: String var `extension`: String var query: [String: String] var httpMethod: String var httpVersion: String var httpHost: String }
  • 82. Swift Protocol Protocol Value Type -> Value Semantics Protocol-Oriented Programming
  • 83. Swift Protocol Protocol Value Type protocol Drawable { func draw() } struct Point: Drawable { func draw() { ... } } struct Line: Drawable { func draw() { ... } } let drawables: [Drawable] = [Point(), Line()] for drawable in drawables { drawable.draw() }
  • 84. Swift Protocol Protocol Type : Memory Allocation Reference Type (8Byte) Value Type Stack
  • 85. Swift Protocol Protocol Type : Memory Allocation protocol Drawable {} struct Point: Drawable { var a: Int } struct Line: Drawable { var x: Int var y: Int } let drawables: [Drawable] = [Point(), Line()] refCount HeapStack ... storage drawables a x y 8 Byte 16 Byte
  • 86. Swift Protocol Protocol Type : Method Dispatch Class -> V-Table Protocol -> V-Table
  • 87. Swift Protocol Existential Container Protocol Type 5 Word (64bit -> 1 Word == 8 Byte) - 3 Word : Value Buffer - 2 Word : Buffer (VWT / PWT ) Protocol Type Existential Container Protocol 3 Word , - 3 Word : Existential Container Value Buffer - 3 Word : Heap , Value Buffer
  • 88. Swift Protocol Value Witness Table (VWT) Existential Container / allocate / copy / destruct / deallocate
  • 89. Swift Protocol Value Witness Table (VWT) 3 Word VWT allocate : X copy : Existential Container destruct : Existential Container deallocate : X
  • 90. Swift Protocol Value Witness Table (VWT) 3 Word VWT allocate : Heap / Existential Container copy : destruct : deallocate : / Existential Container
  • 91. Swift Protocol Protocol Witness Table (PWT) Method Dispatch : Protocol PWT
  • 93. Swift Protocol Copy 3 Word Existential Container a: 10 b: 11 - vwt pwt a: 10 b: 11 - vwt pwt Stack
  • 94. Swift Protocol Copy 3 Word : Existential Container Heap : Heap -> Existential Container * Reference Counting ! Reference Count
  • 96. Swift Protocol Copy ref - - vwt pwt ref - - vwt pwt Stack a: 10 b: 11 c: 12 d: 13 Heap 3 Word : a: 10 b: 11 c: 12 d: 13
  • 97. Swift Protocol Indirect Storage Value Type Reference Type Value Semantics Copy-on-Write isKnownUniquelyReferenced(_:) if !isKnownUniquelyReferenced(&object) { storage = Storage(storage) }
  • 98. Swift Protocol Existential Container Protocol Type Class - Heap (3 Word ) - Dynamic Method Dispatch - Class : V-Table - Protocol : PWT
  • 99. Swift Protocol 3 Word Protocol Type Memory Allocation Stack (Existential Container) Reference Counting No Method Dispatch Dynamic (PWT)
  • 100. Swift Protocol 3 Word Protocol Type Memory Allocation Stack (Existential Container) Heap Reference Counting No Method Dispatch Dynamic (PWT)
  • 101. Swift Protocol Type Type ? Protocol Type Type .
  • 102. protocol SomeProtocol { var a: Int { get } var b: Int { get } } struct SomeStruct: SomeProtocol { var a: Int = 10 var b: Int = 11 } func foo() { var someStruct1 = SomeStruct() var someStruct2: SomeProtocol = SomeStruct() withUnsafeBytes(of: &someStruct1) { print($0) } withUnsafeBytes(of: &someStruct2) { print($0) } } foo()
  • 103. UnsafeRawBufferPointer(start: 0x00007ffeefbff4a0, count: 16) UnsafeRawBufferPointer(start: 0x00007ffeefbff478, count: 40) someStruct2 : (7FFEEFBFF478) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B8 84 00 00 01 00 00 00 38 84 00 00 01 00 00 00 someStruct1 : (7FFEEFBFF4A0) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00
  • 104. sil_witness_table hidden SomeStruct: SomeProtocol module main { method #SomeProtocol.a!getter.1: <Self where Self : SomeProtocol> (Self) -> () -> Int : @$s4main10SomeStructVAA0B8ProtocolA2aDP1aSivgTW // protocol witness for SomeProtocol.a.getter in conformance SomeStruct method #SomeProtocol.b!getter.1: <Self where Self : SomeProtocol> (Self) -> () -> Int : @$s4main10SomeStructVAA0B8ProtocolA2aDP1bSivgTW // protocol witness for SomeProtocol.b.getter in conformance SomeStruct }
  • 106. protocol SmallProtocol { var a: Int { get } var b: Int { get } var c: Int { get } } protocol LargeProtocol { var a: Int { get } var b: Int { get } var c: Int { get } var d: Int { get } } struct SmallStruct: SmallProtocol { var a: Int = 10 var b: Int = 11 var c: Int = 12 } struct LargeStruct: LargeProtocol { var a: Int = 10 var b: Int = 11 var c: Int = 12 var d: Int = 13 } func foo() { var smallStruct: SmallProtocol = SmallStruct() var largeStruct: LargeProtocol = LargeStruct() withUnsafeBytes(of: &smallStruct) { print($0) } withUnsafeBytes(of: &largeStruct) { print($0) } } foo()
  • 107. largeStruct : (7FFEEFBFF460) : 60 D1 54 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 90 85 00 00 01 00 00 00 88 84 00 00 01 00 00 00 smallStruct : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 10 85 00 00 01 00 00 00 68 84 00 00 01 00 00 00
  • 108. (10054D160) : 50 84 00 00 01 00 00 00 02 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 0D 00 00 00 00 00 00 00
  • 109. Swift 3 Word / Copy Copy .
  • 110. Swift 3 Word / Copy Copy .
  • 111. protocol SmallProtocol { var a: Int { get set } var b: Int { get set } var c: Int { get set } } struct SmallStruct: SmallProtocol { var a: Int = 10 var b: Int = 11 var c: Int = 12 } func foo() { var bar1: SmallProtocol = SmallStruct() var bar2 = bar1 // breakpoint 1 bar2.a = 11 // breakpoint 2 withUnsafeBytes(of: &bar1) { print($0) } withUnsafeBytes(of: &bar2) { print($0) } } foo() 3 Word Protocol Type
  • 112. // breakpoint 1 bar2 : (7FFEEFBFF460) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 28 85 00 00 01 00 00 00 50 84 00 00 01 00 00 00 bar1 : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 28 85 00 00 01 00 00 00 50 84 00 00 01 00 00 00 3 Word Protocol Type // breakpoint 2 bar2 : (7FFEEFBFF460) : 0B 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 28 85 00 00 01 00 00 00 50 84 00 00 01 00 00 00 bar1 : (7FFEEFBFF488) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 28 85 00 00 01 00 00 00 50 84 00 00 01 00 00 00
  • 113. protocol LargeProtocol { var a: Int { get set } var b: Int { get set } var c: Int { get set } var d: Int { get set } } struct LargeStruct: LargeProtocol { var a: Int = 10 var b: Int = 11 var c: Int = 12 var d: Int = 13 } func foo() { var bar1: LargeProtocol = LargeStruct() var bar2 = bar1 // breakpoint 1 bar2.a = 11 // breakpoint 2 withUnsafeBytes(of: &bar1) { print($0) } withUnsafeBytes(of: &bar2) { print($0) } } foo() 3 Word Protocol Type
  • 114. // breakpoint 1 bar2 : (7FFEEFBFF460) : 90 B2 B3 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 85 00 00 01 00 00 00 80 84 00 00 01 00 00 00 bar1 : (7FFEEFBFF488) : 90 B2 B3 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 85 00 00 01 00 00 00 80 84 00 00 01 00 00 00 3 Word Protocol Type (103B3B290) : 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 0D 00 00 00 00 00 00 00
  • 115. // breakpoint 2 bar2 : (7FFEEFBFF460) : 70 B8 B3 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 85 00 00 01 00 00 00 80 84 00 00 01 00 00 00 bar1 : (7FFEEFBFF488) : 90 B2 B3 03 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 85 00 00 01 00 00 00 80 84 00 00 01 00 00 00 3 Word Protocol Type (103B3B290) : 68 84 00 00 01 00 00 00 02 00 00 00 00 00 00 00 0A 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 0D 00 00 00 00 00 00 00 (103B3B870) : 78 19 B3 94 FF 7F 00 00 02 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 0D 00 00 00 00 00 00 00
  • 116. Swift Protocol 3 Word Protocol Type vs. Indirect Storage 3 Word Protocol Type Indirect Storage Heap Reference Counting : X Copy-on-Write -> Value Semantics Heap Reference Counting : O Value Semantics Copy-on-Write
  • 117. Swift Generics 3 Word Protocol Type vs. Indirect Storage protocol Drawable { func draw() } struct Point: Drawable { func draw() { ... } } struct Line: Drawable { func draw() { ... } } func draw<T: Drawable>(_ drawable: T) { drawable.draw() } draw(Point()) draw(Line()) Generic Type T Drawable Existential Container T : ->
  • 118. Swift Generics 3 Word Protocol Type vs. Indirect Storage protocol Drawable { func draw() } struct Point: Drawable { func draw() { ... } } struct Line: Drawable { func draw() { ... } } func draw<T: Drawable>(_ drawable: T) { drawable.draw() } draw(Point()) draw(Line()) Generic Specialization Existential Container -> func draw(_ point: Point) { point.draw() } func draw(_ line: Line) { line.draw() } draw(Point()) draw(Line())
  • 120. protocol SomeProtocol { var a: Int { get } } struct SomeStruct1: SomeProtocol { var a: Int = 10 } struct SomeStruct2: SomeProtocol { var a: Int = 11 var b: Int = 12 } func bar<T: SomeProtocol>(_ bar: T) { var bar = bar print(type(of: bar)) withUnsafeBytes(of: &bar) { print($0) } } func foo() { bar(SomeStruct1()) bar(SomeStruct2()) } foo()
  • 121. SomeStruct1 UnsafeRawBufferPointer(start: 0x00007ffeefbff380, count: 8) SomeStruct2 UnsafeRawBufferPointer(start: 0x00007ffeefbff380, count: 16) (7FFEEFBFF380) : 0A 00 00 00 00 00 00 00 (7FFEEFBFF380) : 0B 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00
  • 122. Swift Generics Generics (3 Word Protocol Type) Memory Allocation Stack (Existential Container) Reference Counting No Method Dispatch Dynamic (PWT)
  • 123. Swift Generics Generics (3 Word Protocol Type) Memory Allocation Stack (Existential Container) Heap Reference Counting No Method Dispatch Dynamic (PWT)
  • 124. Swift Generics Generics (Struct) Memory Allocation Stack Reference Counting No Method Dispatch Static
  • 125. Swift Generics Generics (Class) Memory Allocation Heap Reference Counting Yes Method Dispatch Dynamic (V-Table)
  • 128. Struct : Value Semantics Class : Identity / OOP / Objective-C Compatible Generics : Static Polymorphism Protocol : Dynamic Polymorphism
  • 129. Struct Reference Type - Value Type - Reference Counting Protocol Type Struct - Indirect Storage Struct - Mutable Copy-on-Write Method Dispatch : Dynamic -> Static - final / private - dynamic X - Objective-C - WMO
  • 130. .
  • 131. Reference [Swift : Value , Protocol ], , 2016. https://academy.realm.io/kr/posts/letswift-swift-performance/ [Cocoa Internals], , 2017. [Swift Copy-on-Write (CoW)], OAKSONG, 2018. https://oaksong.github.io/2018/01/06/copy-on-write/ [Whole-Module Optimization in Swift 3], Erik Eckstein, 2016 https://swift.org/blog/whole-module-optimizations/ https://github.com/presto95/Study/blob/master/Swift/Whole- Module%20Optimization.md
  • 132. .