2009-01-27 9 views
0

Y at-il un problème de performance lors de l'itération des attributs d'objet par rapport à l'itération d'un tableau?Performances d'ActionScript2: Itérer sur les attributs d'objet

exemple, des objets en utilisant:

var x:Object = {one: 1, two: 2, three: 3}; 
for (var s:String in x) { 
trace(x[s]); 
} 

Vs en utilisant un tableau

var a:Array = [1, 2, 3]; 
var len:Number = a.length; 
for (var i:Number = 0; i < len; ++i) { 
trace(a[i]); 
} 

donc - ce qui est plus rapide et plus important encore par quel facteur? IIRC, dans certaines implémentations JavaScript, l'itération sur les attributs d'objets est plus lente jusqu'à 20x mais je n'ai pas réussi à trouver une telle mesure pour ActionScript2.

Répondre

1

Je viens d'essayer un test très similaire, mais itérer une fois sur 200K éléments, avec des résultats opposés:

Task build-arr: 2221ms 
Task iter-arr: 516ms 

Task build-obj: 1410ms 
Task iter-obj: 953ms 

Je soupçonne que le test de Luc est dominé par les frais généraux de la boucle, ce qui semble plus dans le cas du tableau. Notez également que le tableau a pris beaucoup plus de temps à remplir en premier lieu, donc ymmv si votre tâche est trop lourde.

En outre, dans mon test, stocker longueur d'arret dans une variable locale a donné une augmentation de performance mesurable d'environ 15%.

Mise à jour:

la demande générale, je signale le code je.

var iter:Number = 200000; 
var time:Number = 0; 
var obj:Object = {}; 
var arr:Array = []; 

time = getTimer(); 
for (var i:Number = 0; i < iter; ++i) { 
    arr[i] = i; 
} 
trace("Task build-arr: " + (getTimer() - time) + "ms"); 

time = getTimer(); 
for (var i:Number = 0; i < iter; ++i) { 
    arr[i] = arr[i]; 
} 
trace("Task iter-arr: " + (getTimer() - time) + "ms"); 

time = getTimer(); 
for (var i:Number = 0; i < iter; ++i) { 
    obj[String(i)] = i; 
} 
trace("Task build-obj: " + (getTimer() - time) + "ms"); 

time = getTimer(); 
for (var i:String in obj) { 
    obj[i] = obj[i]; 
} 
trace("Task iter-obj: " + (getTimer() - time) + "ms"); 
+0

Pouvez-vous poster votre code? – Luke

0

OK. Pourquoi ne pas faire quelques mesures simples?

var time : Number; 

time = getTimer(); 

var x:Object = {one: 1, two: 2, three: 3}; 

for(i = 0; i < 100000; i++) 
{ 
    for (var s:String in x) 
    { 
     // lets not trace but do a simple assignment instead. 
     x[s] = x[s]; 
    } 
} 

trace(getTimer() - time + "ms"); 

time = getTimer(); 

var a:Array = [1, 2, 3]; 
var len:Number = a.length; 

for(i = 0; i < 100000; i++) 
{ 
    for (var j : Number = 0; j < len; j++) 
    { 
     a[j] = a[j]; 
    } 
} 

trace(getTimer() - time + "ms"); 

Sur mon ordinateur, l'itération de la baie est un peu plus lente. Cela peut être dû au fait qu'ActionScript 2 ne possède pas de tableaux «réels» mais uniquement des tableaux associatifs (cartes). Apparemment, pour fonctionner avec un tableau, le compilateur doit générer du code supplémentaire. Je n'ai pas examiné les détails de cela, mais je peux imaginer que cela pourrait être le cas.

BTW. Faire ce test pourrait également montrer que mettre la valeur de la longueur du tableau dans une variable n'augmente pas vraiment les performances non plus. MISE À JOUR: Même si ActionScript et JavaScript sont syntaxiquement liés, le mécanisme d'exécution sous-jacent est complètement différent. Par exemple. FireFox utilise SpiderMonkey et IE utilisera probablement une implémentation Microsoft alors que AS2 est exécuté par AVM1 d'Adobe.

+0

Vous ne savez pas pourquoi vous faites le même test 100000 fois? Aussi, comme Simon l'a remarqué correctement, l'initialisation devrait être gardée hors de la mesure ... – moritzstefaner

Questions connexes