COW(Copy-on-Write) λ₯Ό μμ보μ
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 κ°λ°μ μ°μ§±μ κΈ°μ λΈλ‘κ·Έμ
λλ€