티스토리 뷰
안녕하세요 :) Zedd입니다.
OptimizationTips에서 궁금했던.. ContiguousArray......
사실 처음들어봐서 굉장히 궁금해지게 만들었음ㅡㅡ
그래서 공부하려다가..그 전에 Swift github에 "The Swift Array Design"이라는 게 있어서요..
암튼 이거 보고 ContiguousArray를 공부하도록 하겠습니다!!
The Swift Array Design
Goals(목표)
목표 1번과 2를 달성하기 위해, element타입에 대한 정적 지식??..(static knowledge)을 사용합니다. (아 컴파일타임에 알 수 있다는 그런걸 의미하는건가?)
element타입이 클래스가 아닌 것으로 static으로 알려진 경우, NSArray를 wrapping할 가능성을 설명하는 코드 및 검사가 제거됩니다.
Swift value type의 배열의 항상 ContiguousArray와 동일하게, 가능한 한 가장 효율적인 표현(representation)을 사용합니다.
오 ContiguousArray이야기 나와땀
그리고 제가 궁금했던 Swift에서 value type과 reference type의 차이점이, value Type은 NSArray 내부에 포함이 안된다 < 이걸 알 수도 있을지도!?!?!?!?!?!?!?!
Components
Swift는 일반적으로, 3가지 타입의 배열을 제공하며, 모두 amortized O(1) growth를 가집니다.
이 문서에서 ArrayType에 대한 설명은 세가지 타입 모두에 적용됩니다.
● ContiguousArray<Element>는 세가지 타입들 중에서 가장 빠르고 간단합니다.
"C 배열"성능이 필요할 때 사용합니다.
ContiguousArray의 element는 항상 메모리에 연속적으로 저장됩니다.
위 그림처럼 "연속적으로" 저장되는것이 ContiguousArray라고 합니다.
● Array<Element>는 ContiguousArray<Element>와 비슷하지만, Cocoa에서 효율적인 conversions을 위해 최적화되었습니다. Element는 class타입이 될 수 있지만, Array<Element>는 Swift의 ContiguousArray보다 오히려 임의의 NSArray의 저장소에 의해 백업(potentially non-contiguous, contiguous가 아니랍니다) 될 수 있습니다.
Array<Element>는 관련된 class타입의 배열 사이에서, 업 / 다운 캐스트를 지원합니다.
Element가 클래스가 아닌 타입으로 알려진 경우(== 값타입인 경우) Array<Element>의 성능은 ContiguousArray<Element>의 성능과 동일합니다.
엄청 중요한 말들이 지나간 느낌인데요..
"Swift에서 value type과 reference type의 차이점이, value Type은 NSArray 내부에 포함이 안된다 "
이게...이게 그니까 지금은 만약에 Element가 클래스타입이면, 즉 reference type이면 임의의 NSArray저장소에 의해 백업될 수 있다. 그니까 NSArray 내부에 포함될 수 있다. 근데 value type이면 안그런다????? 그뜻인거 같은데여?!?!?!?!?!?!?!?
마지막줄 보면 value type이면 "Array<Element>의 성능은 ContiguousArray<Element>의 성능과 동일합니다." < 이라고 했으니까 value type이면 연속적으로 저장된다는 것인가??!?!?!?????????????? 그래서 "Swift에서 value type과 reference type의 차이점이, value Type은 NSArray 내부에 포함이 안된다 "
● ArraySlice<Element> 는 Array<Element> 또는 ContiguousArray<Element>의 subrange입니다. ArraySlice<Element>는 slice notation(slice 표기법)을 사용한 결과입니다. (e.g. 이름이 a인 Swift배열에서 a[7...21] )
slice에는 항상 contiguous storage 및 "C 배열" 성능을 가집니다.
contiguous storage를 제공하지 않는 NSArray에 의해 백업되는 소스가 Array<Element>가 아닌이상(위에서 말한 value type이 아닌 reference type == 클래스타입을 담았을 때, NSArray에 백업될 수 있다고 그랬잖아요?) ArrayType을 slice하는 것은 O(1)입니다.
ArraySlice는 일시적인(transient) 계산에는 권장되지만, 장기 저장(long-term storage)에는 권장되지 않습니다.
일부 공유된 백업 버퍼의 sub-range를 참조하기 때문에 ArraySlice는 ArraySlice 외부 요소의 lifetime을 인위적으로 연장 할 수 있습니다.
Mutation Semantics
var a = [1, 2, 3]
let b = a
a[1] = 42
print(b[1]) // prints "2"
Bridging Rules and Terminology for all Types
protocol _BridgedToObjectiveC {
typealias _ObjectiveCType: AnyObject
func _bridgeToObjectiveC() -> _ObjectiveCType
class func _forceBridgeFromObjectiveC(_: _ObjectiveCType) -> Self
}
Note : 클래스와 @objc existentials은 _BridgedToObjectiveC를 준수하지 않아야 합니다. 제한(restriction)은 컴파일타임에 적용 할 수 없습니다.
일부 Generic type(ArrayType<T>)은 element타입이 브릿징 될 경우에만 Objective-Cㅇㅔ 브릿징됩니다. 이러한 타입은 _ConditionallyBridgedToObjectiveC를 준수합니다.
protocol _ConditionallyBridgedToObjectiveC : _BridgedToObjectiveC {
class func _isBridgedToObjectiveC() -> Bool
class func _conditionallyBridgeFromObjectiveC(_: _ObjectiveCType) -> Self?
}
T._isBridgedToObjectiveC()가 false일 때, _ConditionallyBridgedToObjectiveC를 준수하는 유형 T에서 브릿징하는것은 런타임에 진단 될 수 있는 사용자 프로그래밍 에러입니다.
_conditionallyBridgeFromObjectiveC를 사용하여 다시 브릿징 하려고 시도하고, 전체 객체를 브릿징 할 수 없는 경우, nil을 반환합니다.
Implementation Note : 이러한 detection을 컴파일타임으로 옮기는 다양한 방법이 있습니다.
있다는데, 이건 알아서 읽어보시길.
이 이후에 정말 알아들을 수 없는 내용들이 나오는데, 이것도 알아서 읽으시길 바랍니다.
근데 이 이후에 나오는 내용들을 요약??한 것이 Array문서에 언급이 되어있는 것 같아서 이거는 공부해보도록 하겠습니닷 XD
Bridging Between Array and NSArray
Array가 아닌 NSArray 인스턴스의 데이터가 필요한 API에 접근해야하는 경우, type-cast연산자인 as를 사용하여 인스턴스를 브릿징하세요. (연결하라는 뜻임) 브릿징이 가능하려면, 배열의 element타입이 클래스, @objc프로토콜(Objective-C에서 가져온 프로토콜 또는 @objc 속성으로 표시된 프로토콜) 또는 Foundation타입에 브릿징되는 타입이어야 합니다.
다음 예제에서는 Array인스턴스를 NSArray에 브릿징하여 write(to:atomically:)메소드를 사용하는 방법을 보여줍니다.
let colors = ["periwinkle", "rose", "moss"]
let moreColors: [String?] = ["ochre", "pine"]
let url = NSURL(fileURLWithPath: "names.plist")
(colors as NSArray).write(to: url, atomically: true)
// true
(moreColors as NSArray).write(to: url, atomically: true)
// error: cannot convert value of type '[String?]' to type 'NSArray'
colors배열의 String element가 NSString으로 브릿징 될 수 있기 때문에, colors배열을 NSArray에 브릿징 할 수 있습니다.
하지만, 컴파일러는 Element타입이 Foundation타입에 브릿징 되지 않는 Optional<String> = String? 이므로 moreColors배열이 브릿징되지 못합니다.
배열 element가 이미 클래스 또는 @objc프로토콜의 인스턴스인경우, Array에서 NSArray로의 브릿징은 O(1)시간과 O(1)공간을 사용합니다. 그렇지 않으면 == 배열 element가 클래스 || @objc프로토콜의 인스턴스가 아닌경우 O(n) 시간/공간이 필요합니다.
destination 배열(대상 배열...?)의 element타입이 클래스 또는 @objc프로토콜 인경우, NSArray에서 Array로의 브릿징은,
먼저 배열의 copy(with:)
(- copy
in Objective-C) 메소드를 호출 하여 immutable(변경 불가능한) 복사본을 가져온 다음, O(1)시간이 걸리는 Swift bookkeeping작업(bookkeeping이라는 뜻이 사업의 재무(financial)기록을 하는 그런 활동을 의마한다는데...)을 수행합니다.
이미 immutable인 NSArray인스턴스의 경우, copy(with:)는 대게 O(1)시간에 동일한 배열을 반환합니다.
copy(with:)가 동일한 배열을 반환하면, NSArray및 Array 인스턴스는 Array의 두 인스턴스가 저장소를 공유 할 때 사용되는 것과 동일한 copy-on-write optimization을 사용하여 저장소를 공유합니다.
destination배열의 element타입이 Foundation타입에 연결되는 non-class type인 경우, NSArray에서 Array로의 브릿징은 element를 O(n)시간에 contiguous storage에 복사본을 브릿징합니다.
예를들어, NSArray에서 Array<Int>로의 브릿징은 이러한 copy를 수행합니다. Array인스턴스의 element에 접근 할 때, 추가 브릿징이 필요하지 않습니다.
ContiguousArray 및 ArraySlice타입은 브릿징되지 않습니다. ContiguousArray 및 ArraySlice는 항상 contiguous(연속적인) 메모리 블록을 스토리지로 사용합니다.
gㅎㅎㅎㅎ이렇게...알아보았는데요,
In Swift, types can be divided into two different categories: value types (structs, enums, tuples) and reference types (classes). A key distinction is that value types cannot be included inside an NSArray."
이렇게 inside라고 말한 이유가 있었군요...ㅎㅎ헿ㅎ핳ㅎㅎㅎ그래도 왜 문서에서 이렇게 말했는지 이유를 알아서 기분 좋네요!!
도움이 되었길 바랍니다 :)
'Swift' 카테고리의 다른 글
Swift ) Swift Sorting Algorithm (4) | 2018.12.26 |
---|---|
Swift ) ContiguousArray / ArraySlice (0) | 2018.09.28 |
WWDC 2018 ) What's New in Cocoa Touch (6) | 2018.09.27 |
Swift ) (3) Understanding Swift Performance (Swift성능 이해하기) (1) | 2018.09.25 |
Swift ) (2) Understanding Swift Performance (Swift성능 이해하기) (2) | 2018.09.24 |
- WWDC
- WKWebView
- Accessibility
- fastlane
- SwiftUI
- Git
- swift delegate
- swift3
- IOS
- 회고
- swift tutorial
- Xcode
- swift array
- swift 공부
- ios 13
- github
- 피아노
- iOS delegate
- np-complete
- FLUTTER
- swift sort
- Swift
- 제이슨 파싱
- Combine
- 스위프트 문법
- UIBezierPath
- WidgetKit
- actor
- 스위프트
- np-hard
- Total
- Today
- Yesterday