2016-10-04 1 views
5

In the Swift Language Reference, under String Mutability il dit:Est-ce que Swift a une concaténation de chaîne quadratique lors de l'utilisation de var?

Vous indiquez si une chaîne particulière peut être modifié (ou muté) en attribuant à une variable (dans ce cas, il peut être modifié), ou à une constante (auquel cas il ne peut pas être modifié)

on ne sait pas à moi si le « il » qui est mutable est la variable ou la valeur .

Par exemple, si je vous écris:

var s = "" 
for i in 0...100 { 
    s += "a" 
} 

est-il semblable à la création d'un NSMutableString et d'appeler appendString 100 fois (c.-à-coût linéaire)?

Ou est-ce semblable à la création d'une série d'instances NSString toujours plus grandes et en les combinant avec stringByAppendingString (à savoir le coût quadratique)?

Ou peut-être crée-t-il une sorte de structure de corde dans les coulisses, donc et sont-ils linéaires?

+1

@MarkDickinson J'ai effectivement essayé cela, et il a fonctionné beaucoup plus vite que prévu. Donc, cela semblerait impliquer mutable. Mais, lorsque deux variables mutables sont définies l'une par rapport à l'autre, la mise à jour d'une variable ne met pas à jour l'autre, ce qui implique qu'elle est immuable. Et du point de vue de la conception du langage, il semble vraiment étrange de mettre des informations de type runtime dans var-vs-val. Donc, je ne suis vraiment pas sûr de ce que c'est. –

Répondre

2

L'ajout d'une collection comme celle-ci (alors que String n'est pas en elle-même une collection, vous ajoutez essentiellement à sa vue characters avec ce code) est linéaire, et non quadratique. Une chaîne dans Swift a un tampon interne dont la taille est doublée chaque fois qu'elle se remplit, ce qui signifie que vous verrez de moins en moins de réaffectations à mesure que vous ajoutez plusieurs fois. La documentation décrit l'ajout de cette manière comme une opération O (1) «amortie»: la plupart du temps, l'ajout est O (1), mais occasionnellement, il faudra réallouer le stockage de la chaîne. Les tableaux, ensembles et dictionnaires ont le même comportement, bien que vous puissiez également réserver une capacité spécifique pour un tableau (en utilisant reserveCapacity(_:)) si vous savez que vous ajouterez plusieurs fois. Toutes ces collections utilisent "copy-on-write" pour garantir la sémantique des valeurs. Ici, x et y partagent un tampon:

let x = "a" 
let y = x 

Si vous muter x, il obtient une nouvelle copie unique du tampon:

x += "b" 
// x == "ab" 
// y == "a" 

Après cela, x a son propre tampon, si la suite les mutations ne nécessiteront pas de copie.

x += "c" // no copy unless buffer is full 
+0

Ceci demande un lien vers la source stdlib ;-) – jtbandes

+0

@jtbandes Que diriez-vous d'un lien vers la documentation? ;) https://developer.apple.com/reference/swift/string#2621389 –

+0

Pourriez-vous entrer dans un peu plus de détails sur la sémantique de 'var string' pour justifier cette réponse?Par exemple, pourquoi 'var x =" a "; var y = x; x + = "b"; print (y) "print" a "au lieu de" ab "s'il n'y a qu'un tampon commun dans lequel est ajouté? –