2017-02-18 1 views
1

Je tente de créer une fonction de masque de données.Best Data get/set uint8 à l'index/Masquage des données

J'ai trouvé deux façons:

  1. en utilisant les indices de données

    • très lent
  2. tableau création à partir des données, les modifier puis reconvertir

    • ~ 70 fois plus rapide
    • utilise 2 fois plus de mémoire

Pourquoi subscripting données est si lent? Existe-t-il un meilleur moyen d'obtenir/définir uint8 à l'index sans dupliquer la mémoire?

voici mon test:

var data = Data(bytes: [UInt8](repeating: 123, count: 100_000_000)) 

let a = CFAbsoluteTimeGetCurrent() 

// data masking 
for i in 0..<data.count { 
    data[i] = data[i] &+ 1 
} 

let b = CFAbsoluteTimeGetCurrent() 

// creating array 
var bytes = data.withUnsafeBytes { 
    [UInt8](UnsafeBufferPointer(start: $0, count: data.count)) 
} 
for i in 0..<bytes.count { 
    bytes[i] = bytes[i] &+ 1 
} 
data = Data(bytes: bytes) 

let c = CFAbsoluteTimeGetCurrent() 
print(b-a) // 8.8887130022049 
print(c-b) // 0.12415999174118 

Répondre

1

Je ne peux pas vous dire exactement pourquoi la première méthode (via subscripting la valeur Data) est si lent. Selon Instruments, beaucoup de temps est passé en objc_msgSend, lors de l'appel des méthodes sur l'objet sous-jacente NSMutableData.

Mais vous pouvez muter les octets sans copier les données à un tableau: Méthode

data.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer<UInt8>) -> Void in 
    for i in 0..<data.count { 
     bytes[i] = bytes[i] &+ 1 
    } 
} 

qui est encore plus rapide que votre « copie au tableau ».

Sur un MacBook j'ai obtenu les résultats suivants:

  • données subscripting: 7.15 sec
  • Copier sur tableau et arrière: 0,238 sec
  • withUnsafeMutableBytes: 0,0659 sec