2010-10-20 4 views
0

je suis tombé à travers une présentation (dalvik-vm-internals) sur Dalvik VM, en ce qu'il est mentionné comme pour les boucles ci-dessous, nous avons utilisation (2) et (3) et éviter (7).boucles efficacité

(1) for (int i = initialiseur; i> = 0; i--)

(2) limite int = limite de calculer; pour (int i = 0; i < limite; i ++)

(3) Type [] array = get array; pour (Type obj: array)

(4) for (int i = 0; i < array.length; i ++)

(5) for (int i = 0; i < this.var; i ++)

(6) pour (int i = 0; i < obj.size(); i ++)

(7) liste Iterable = obtenir la liste; pour (Type obj: liste)

Commentaires: Je pense que (1) et (2) sont les mêmes. (3) (4) chaque fois qu'il doit calculer la longueur de tableau, donc cela peut être évité (5) (6) même que (4), en calculant la taille à chaque fois (7) a demandé d'éviter comme liste est d'un type Iterable ??

un de plus, dans le cas si nous disposons de données infinies (en supposant que les données sont à venir comme un flux) qui boucle devrait-on envisager pour une meilleure efficacité?)

demande vous plaît commenter ce ...

+0

Cette présentation date de 2008, bien avant l'introduction du compilateur JIT dans Froyo. http://developer.android.com/guide/practices/design/performance.html#foreach est plus récent mais je pense que ce document est aussi un peu démodé. (Une version mise à jour devrait apparaître sur ce site lorsque la prochaine version sortira.) – fadden

+0

Merci pour le lien !! cela a été utile – Vamsi

Répondre

0

Si c'est ce qu'ils recommandent, c'est ce qu'ils ont optimisé le compilateur et la machine virtuelle. Ceux que vous estimez identiques ne sont pas nécessairement implémentés de la même manière: le compilateur peut utiliser toutes sortes de trucs avec l'analyse des données et des chemins pour éviter des opérations naïvement coûteuses. Par exemple, le résultat array.length() peut être mis en cache car les tableaux sont immuables.

Ils sont classés du plus au moins efficace: mais (1) est «non naturel». Je suis d'accord, n'est-ce pas? Le problème avec (7) est qu'un objet itérateur est créé et doit être GC'ed.

Noter avec attention quand le conseil doit être pris en compte. Il est clairement destiné itération itération sur une collection connue, pas le cas de flux. Ce n'est pertinent que si la boucle a un effet significatif sur les performances et la consommation d'énergie («fonctionnement à l'échelle de l'ordinateur»). La première loi de l'optimisation est "Ne pas optimiser". La deuxième loi (pour les experts) est "Ne pas optimiser, encore.". Mesurez d'abord (à la fois les temps d'exécution et la consommation du processeur), optimisez plus tard: cela s'applique même aux appareils mobiles.

Ce que vous devriez considérer sont les diapositives précédentes: essayez de dormir aussi souvent et aussi longtemps que possible, tout en répondant rapidement aux changements. Comment vous faites cela dépend du type de flux que vous traitez. Enfin, notez que la présentation date de deux ans et qu'elle ne s'applique pas complètement à 2 ans.2 appareils où entre autres choses JIT est mis en œuvre.

+0

Oui, je pense que j'ai simplifié !! mais at-il une différence entre (1) et (2), à cause du post-décrément et post-incrément? – Vamsi

+0

Voir ma révision. La comparaison à un entier arbitraire est généralement implémentée comme une soustraction et une comparaison à zéro, donc (1) a un très léger avantage sur la performance (2), mais nous oblige à penser en arrière (et rend le code moins supportable). Optez pour (1) uniquement si vous savez ** qu'il existe un goulot d'étranglement des performances ou un point d'accès de la puissance du processeur dans ce code. Et même alors ... –

+0

Merci! c'était une très bonne explication. – Vamsi

0

Avec des données infinies, aucun des exemples n'est assez bon. Meilleur serait de faire

for(;;) { 
    list.poll(); //handle concurrency, in java for example, use a blocking queue 
} 
+0

cela a-t-il une différence si nous utilisons ... while (1) {list.poll();}? – Vamsi

+0

Ça ne devrait pas faire la différence, non. – krico

0

1) et 2) sont vraiment différents. 2) besoin d'une soustraction supplémentaire pour calculer i = 0 non. Encore mieux, sur la plupart des processeurs (et code bien optimisé), aucune comparaison n'est nécessaire pour i> = 0. Le processeur peut utiliser le negative flag, résultant de la dernière diminution (i--).

Ainsi, la fin de la boucle -1 ressemble (en assembleur pseudo)

--i 
jump-if-neg 

while # 2

++i 
limit-i # set negative flag if i >limit 
jump-if-neg 

Cela ne fait pas une grande différence, sauf si le code dans votre boucle est vraiment petit (comme l'opération de base de la chaîne C) Cela pourrait ne pas fonctionner avec les langages interprétés.