Sobes.tech
Middle+

Pastāstiet man par kopēšanas optimizācijas mehānismu iOS.

sobes.tech AI

Atbilde no AI

Mehānisms, kas optimizē kopēšanu iOS un macOS, bieži saistīts ar Copy-on-Write (CoW) struktūru vai vērtības semantiku, ļauj izvairīties no liekas datu kopēšanas, pārsūtot struktūras vai klases ar vērtības semantiku, piemēram, masīvus, vārdnīcas, virknes un pat savas struktūras, ja tās īsteno Equatable un Hashable protokolus (ne stingri, bet tipisks gadījums).

CoW būtība:

  1. Izveidojot struktūras kopiju (piemēram, piešķirot vienu mainīgo citai vai nododot funkcijai kā vērtību), faktiska datu kopēšana nenotiek. Abas mainīgās norāda uz tās pašas datu vietas atmiņā. Saites skaitītājs palielinās.
  2. Kopēšana tiek atlikta, līdz viena no kopijām mēģina mainīt datus.
  3. Tikai izmaiņas brīdī dati tiek patiesi kopēti, un jau jaunā kopija tiek mainīta. Sākotnējā kopija turpina norādīt uz sākotnējiem datiem, ja tai ir vismaz viens īpašnieks.

Priekšrocības:

  • Samazina kopēšanas operāciju izmaksas, īpaši lieliem datu apjomiem (masīviem, virknes).
  • Samazina atmiņas izmantošanu, jo vairākas vienības var koplietot tos pašus datus.
  • Paaugstina veiktspēju, pārsūtot struktūras ar vērtības semantiku.

Piemēri, kur CoW aktīvi tiek izmantots:

  • NSArray, NSDictionary, NSString: Objective-C šajās klasēs izmanto CoW optimizācijai.
  • Swift Array, Dictionary, String: Šie pamattipi Swift ir ar vērtības semantiku un izmanto CoW.
var array1 = [1, 2, 3]
var array2 = array1 // Datu kopēšana nenotiek, abas mainīgās norāda uz to pašu datu kopu

array2.append(4) // Notiek patiesa datu kopēšana array2, pēc tam pievienošana
// Tagad array1 = [1, 2, 3], un array2 = [1, 2, 3, 4]

Svarīgi punkti:

  • Mazas papildu izmaksas pārbaudei, vai nepieciešama kopēšana, katras izmaiņas laikā.
  • Slēpta kopēšana, kas var ietekmēt veiktspēju negaidītās vietās.

Svarīgi atcerēties, ka CoW efektīvi darbojas struktūrās ar vērtības semantiku (struct, enum). Klases ir atsauces semantika, un, piešķirot vai nododot klases instanci, tiek kopēta tikai saite, nevis paši dati.

Lielākā daļa iebūvēto kolekciju un virkņu Swift darbojas ar vērtības semantiku un izmanto CoW. Izveidojot savas struktūras, kas satur atsauces tipus (piemēram, klasi), CoW tiks piemērots pašai struktūrai, bet ne atsauces tipa saturam. Izmaiņas atsauces tipa īpašībā, kas atrodas struktūras iekšpusē, nesāks izsaukt CoW visai struktūrai, bet var prasīt CoW pašam atsauces tipam, ja tas to atbalsta.

Savu datu tipu manuāla īstenošana ar CoW Swift'ā var tikt veikta, izmantojot atsauces tipu kombināciju datu glabāšanai (piemēram, klase ar iekšēju struktūru) un unikālas saites pārbaudi pirms izmaiņām (isKnownUniquelyReferenced):

class Container<T> {
    var value: T

    init(_ value: T) {
        self.value = value
    }
}

struct CustomStruct {
    private var _container: Container<[Int]>

    var data: [Int] {
        get { return _container.value }
        set {
            // Pārbaudām, vai konteineris ir unikāls
            if !isKnownUniquelyReferenced(&_container) {
                _container = Container(newValue)
            } else {
                _container.value = newValue
            }
        }
    }

    init(data: [Int]) {
        _container = Container(data)
    }
}

var s1 = CustomStruct(data: [1, 2, 3])
var s2 = s1 // CoW: _container s1 un s2 tagad norāda uz to pašu Container

s2.data.append(4) // Setter data tiek izsaukts:
                   // isKnownUniquelyReferenced(_container) — false (jo s1 arī norāda uz to)
                   // Tiek izveidots jauns Container ar kopiju [1, 2, 3, 4], s2._container norāda uz to
                   // s1._container joprojām norāda uz veco Container, [1, 2, 3]

print(s1.data) // Izvade: [1, 2, 3]
print(s2.data) // Izvade: [1, 2, 3, 4]