-
COW(Copy-on-Write) λ₯Ό μμ보μiOS/π Swift 2022. 12. 29. 23:34
Copy-on-Write
κ°μ μ€μ λ‘ μΈ λ (on-write) 볡μ¬νλ€(copy)
μ€μ 볡μ¬λ₯Ό λ¦μΆμ΄ ν ν λΉμ μ€μ΄λ μ΅μ ν λ°©λ²
Usecases
1. Swift Collection : Array, Dictionary, String λ±
2. 3-word κ° λλ struct λ₯Ό Protocol νμ μΌλ‘ λ€λ£° λ
κ° νμ κ³Ό ν μμμ κ΄κ³
Array λ String μ μ€μννΈμμ κ° νμ μ λλ€.
κ° νμ μΈμ€ν΄μ€λ κΈ°λ³Έμ μΌλ‘ μ€ν μμμ ν λΉνκ³ κ·Έ κ³³μ κ°μ μ΄κΈ°ννλ κ²μΌλ‘ μλ €μ Έ μμ΅λλ€.
κ·Έλ¬λ©΄ κ° νμ κ³Ό ν μμμ μ΄λ€ κ΄λ ¨μ΄ μμκΉμ?
Arrray, String λ± Collection μ νμ©νλ νΉμ κ° νμ λ€μ λ°νμμ element μ μΆκ°, μμ κ° κ°λ₯νκΈ° λλ¬Έμν μμ λ°μ΄ν°λ₯Ό μν 곡κ°μ λ΄λΆμ μΌλ‘ ν λΉν©λλ€.
κ·Έλ°λ° μ΄ νμ λ€μ κ° νμ μ΄κΈ° λλ¬Έμ value-semantic μ κ°μ ΈμΌν©λλ€.
value-semnantic μ νΉμ§μ 볡μ¬ν λλ§λ€ κΉμ 볡μ¬κ° μΌμ΄λλ κ²μ λλ€.
μ μ¬μ€ λλ¬Έμ μ΄ νμ λ€μ κ°μ 볡μ¬ν λλ§λ€ ν ν λΉμ΄ μΌμ΄λμΌν©λλ€.
κ° νμ μ νΉμ± λλ¬Έμ, μΈμ€ν΄μ€λ§λ€ λ 립μ μΈ λ°μ΄ν°λ₯Ό κ°μ§κ³ μμ΄μΌνκΈ° λλ¬Έμ λλ€.
ν ν λΉκ³Ό μ±λ₯
ν ν λΉμ κ°λ₯ν κ·Έ νμλ₯Ό μ€μ¬μΌνλ μ±λ₯ μ ν΄ μμ μ€ νλμ λλ€.
Arrray, String λ± Collection μ νμ©νλ νΉμ κ° νμ λ€μ λ³΅μ¬ μ λ°μνλ ν ν λΉμ μ€μ΄κΈ° μν΄ COW λ₯Ό μ¬μ©ν©λλ€.
COW λ κ°μ μμ λμ λ μ€μ 볡μ¬κ° μΌμ΄λμ κ²°κ³Όμ μΌλ‘ ν ν λΉ μλ₯Ό μ€μ΄λ μ±λ₯ μ΅μ ν κΈ°μ μ λλ€.
COW λ₯Ό μ¬μ©νλ©΄ κ° νμ μ μ₯μ ( No unintended sharing of state ) μ κ°μ Έκ°λ©΄μ value-semantic λλ¬Έμ μκΈ°λ λΆνμν ν ν λΉμ μ€μΌ μ μμ΅λλ€.μ΄ κΈμμλ ν ν λΉμ΄ μ±λ₯μ μ΄λ€ μν₯μ μ£Όλμ§ λ€λ£¨μ§λ μμ΅λλ€.
κ΄λ ¨ λ΄μ©μ WWDC 16: Understanding Swift Performance μμμ μ°Έκ³ νμλ©΄ μ’μ κ² κ°μ΅λλ€.
ν μ£Όμλ₯Ό νμΈν΄μ COW κ° μΌμ΄λλμ§ μ¦λͺ νκΈ°
μ΄λ€ νμ μ΄ COW κ° μΌμ΄λλ€κ³ ν λ, λ€μκ³Ό κ°μ΄ λμν¨μ μμν μ μμ΅λλ€.
1. λ³΅μ¬ λμ μμλ λμΌν ν μμμ 곡μ νλ€.
2. μμ λμμ΄ μΌμ΄λ λ λ 립μ μΈ ν μμμ ν λΉ/ μ΄κΈ°ννκ³ μμ μ¬νμ λ°μνλ€.
κ°λ¨ν μ½λλ‘ λ³΄λ©΄ λ€μκ³Ό κ°μ΅λλ€.var array1 = [1,2,3] var array2 = array1 // λ³΅μ¬ λμ, μ΄ λλ κ°μ ν μμμ 곡μ νλ€. array2.append(4) // μμ λμ, array1 κ³Ό λ€λ₯Έ λ 립μ μΈ ν μμμ μ¬μ©νλ€.
μ΄κ²μ μ¦λͺ ν λμ ν΅μ¬μ μΈμ€ν΄μ€κ° μ¬μ©νκ³ μλ ν μμμ ν¬μΈν°λ₯Ό μ»μ΄μΌνλ€λ κ²μ λλ€.
κ° νμ , μ°Έμ‘° νμ κ³Ό κ΄λ ¨μμ΄ μ€ν μμμ μΈμ€ν΄μ€λ§λ€ νμ λ 립μ μΌλ‘ ν λΉλκΈ° λλ¬Έμ,
μ€ν μμ μ£Όμλ₯Ό νμΈνλ κ²μ μλ―Έκ° μμ΅λλ€.
κ·Έλ λ€λ©΄ ν¬μΈν°λ μ΄λ»κ² μ»μ μ μμκΉμ?
μ°μ ν¬μΈν°λ μ£Όμλ₯Ό μ μ₯ν μ μλ λ³μμ λλ€.
κΈ°λ³Έμ μΌλ‘ νΉμ κ°μμ μ»μ΄λΈ ν¬μΈν°λ κ°μ΄ ν λΉλ λ©λͺ¨λ¦¬μ μμμ£Όμλ₯Ό λ΄κ³ μμ΅λλ€.
C ν¬μΈν°λ₯Ό μ΄ν΄νκΈ° μν΄ κ°λ¨νκ² μ 리ν λ Έμ λ§ν¬λ₯Ό 첨λΆν©λλ€. (λ§ν¬)
μ€μννΈλ ARC λ₯Ό ν΅ν΄ λ©λͺ¨λ¦¬λ₯Ό κ΄λ¦¬νκ³ μκ³ , λ©λͺ¨λ¦¬ μμ μ±μ μν΄ ν¬μΈν° μ¬μ©μ μ§μν©λλ€.
νμ§λ§ μ€μνΈνλ C μΈμ΄μμ μνΈμ΄μ©μ±μ μν΄ Unsafe, Unmanaged λΌλ prefix λ‘ μμνλ API λ₯Ό μ 곡ν©λλ€.
κ·Έλ¦¬κ³ μ€μννΈλ μ€μννΈ κ°μ ν¬μΈν°λ‘ μλμΌλ‘ λ³νν΄μ£Όλ νΈλ¦¬ν κΈ°λ₯μ μ 곡ν©λλ€.
μ λ μ΄ κΈ°λ₯μ νμ©νμ¬ μΈμ€ν΄μ€μ ν¬μΈν°λ₯Ό μ»μ΄μ μ£Όμλ₯Ό νμΈν κ²μ λλ€.μ£Όμ΄μ§ μ£Όμκ° ν μμμΈμ§ μ€ν μμμΈμ§ μ μ μλ λ°©λ²
zsh λͺ λ Ήμ΄λ₯Ό ν΅ν΄ νλ‘μΈμ€μ λ©λͺ¨λ¦¬ μμμ΄ μ΄λ»κ² ꡬμ±λμ΄μλμ§ νμΈνκ³ ,
μ£Όμ΄μ§ μ£Όμκ° μ΄λ€ μμμ ν¬ν¨λλμ§ νλ¨ν μ μμ΅λλ€.
ν μμ
vmmap <PID> | grep Malloc
MALLOC_TINY, MALLOC_SMALL, MALLOC_NANO λ±μ μ΄λ¦μΌλ‘ ν λΉ λ κ²μ νμΈν μ μμ΅λλ€.
μ€ν μμvmmap <PID> | grep Stack
thread λ§λ€ μ€ν μμμ΄ ν λΉλμκ³ κ° μμμ μ£Όμ λ²μλ₯Ό νμΈν μ μμ΅λλ€.μ£Όμλ₯Ό μ»λ λ©μλ ꡬν
func address<T>(of: UnsafePointer<T>) { let result = String(format: "%018p", of) print(result) } /// String ν μμ μ κ·Όμ μν΄μ νμ!! func address(with: UnsafePointer<CChar>) { let result = String(format: "%018p", with) print(result) }
Array νμΈνκΈ°
UnsafePointer<Int> λ‘ λ³ννλ©΄ ν μμ μ£Όμλ₯Ό κ°μ Έμ¬ μ μμ΅λλ€.
* μΆκ° μ 보: Array<T> λ μ€ν λ΄ ν λΉλλ μ¬μ΄μ¦κ° νμ 8λ°μ΄νΈμμ΅λλ€. (λ νΌλ°μ€λ§ μ μ₯ν¨μ μ μΆν μ μμ΅λλ€)
νμΈ κ²°κ³Ό Array λ COW μ΄ μλνλ κ²μ νμΈν μ μμμ΅λλ€.String νμΈνκΈ°
μ΄λ² νμ΅μ ν΅ν΄ μκ²λ μ¬μ€μ λλ€.
String μ ν¬μΈν° νμ μ λ°λΌ λ€λ₯Έ μ£Όμλ₯Ό κ°μ Έμ΅λλ€.
UnsafePointer<String> λ‘ λ³ννλ©΄ μ€ν μμ μ£Όμλ₯Ό κ°μ Έμ΅λλ€. (const String *)
UnsafePointer<CChar> λ‘ λ³ννλ©΄ λ΄λΆμ μΌλ‘ κ΄λ¦¬νλ ν μμ μ£Όμλ₯Ό κ°μ Έμ΅λλ€. (const char *)
* μ¬κΈ°μ char * λ C μμ λ¬Έμμ΄ ν¬μΈν°μ ν΄λΉν©λλ€.νμΈ κ²°κ³Ό String μ COW μ΄ μλνλ κ²μ νμΈν μ μμ΅λλ€.
* 짧μ λ¬Έμμ΄μ κ²½μ° μ€ν μμλ§ μ¬μ©νκΈ° λλ¬Έμ μ΄ λ μ»λ ν μ£Όμλ μλ―Έμλ κ°μΌλ‘ νλ¨νμμ΅λλ€.
μ§μ COW λ₯Ό ꡬννκΈ°
μλ λ§ν¬μ μμΈν λμμμ΄ μμΈν λ΄μ©μ μλ΅ν©λλ€.
ꡬνμ ν΅μ¬μ struct μ΄ μ°Έμ‘°νμ μμ±μ ν΅ν΄ indirect storage λ₯Ό κ°μ§κ³ ,
λ³΅μ¬ μ λμΌν μ°Έμ‘°νμ μΈμ€ν΄μ€λ₯Ό 곡μ ν©λλ€.
μ΄ ν κ°μ μμ ν μ `isKnownUniquelyReferenced()` API λ₯Ό ν΅ν΄ μ°Έμ‘°νμ μΈμ€ν΄μ€μ μ°Έμ‘° κ°μλ₯Ό νμ ν©λλ€.
λ§μ½ 1κ° μ΄μμΌ κ²½μ° κ·Έ λμμΌ λ 립μ μΈ λ³΅μ¬λ³Έ μΈμ€ν΄μ€λ₯Ό λ§λ€κ³ κ·Έ κ°μ μμ ν©λλ€.κ°μ΄ 보면 μ’μ μμ
μλλ μ λ΄μ©μ μ μ΄ν΄νκΈ° μν΄ κ°μ΄ 보면 μ’μ μμλ€μ λλ€.
μμμ μ§μ λ³΄κ³ νμ΅νλκ²μ΄ κ°μ₯ μ’μ΅λλ€.
λ―Έν‘νμ§λ§ μ κ° μ 리ν λ Έμ λ§ν¬λ₯Ό μΆκ°λ‘ λ¨κΉλλ€.WWDC 16 Understatnding Swift Performance [ μμ λ§ν¬ , λ Έμ λ§ν¬ ]
WWDC 18 iOS Memory Deep Dive [μμ λ§ν¬, λ Έμ λ§ν¬]
WWDC 20 Unsafe Swift [μμ λ§ν¬, λ Έμ λ§ν¬]κ°μ΄ 보면 μ’μ κΈ
Rome was not built in a day π
π€ [Back to the Basics] π»
μ£Όλμ΄ iOS κ°λ°μ μ°μ§±μ κΈ°μ λΈλ‘κ·Έμ λλ€'iOS > π Swift' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[Swift] Swift 5.8 CHANGELOG (0) 2022.11.27 [Swift] didSet μ΄ νΈμΆλλ μ°λ λλ? (2) 2022.11.06 [Swift] if case let λ₯Ό μ¬μ©νμ¬ λΆνμν μ½λ μ€μ΄κΈ° (4) 2022.01.16 [Swift] Any μ AnyObject (0) 2021.10.16 [Swift] Metatype μ΄λ? (2) 2021.10.02