55 votes

Boucle 'for' contre 'foreach' de Qt en C++.

Qu'est-ce qui est le mieux (ou le plus rapide), un C++ ? for ou la boucle foreach fourni par Qt ? Par exemple, la condition suivante

QList<QString> listofstrings;

Lequel est le meilleur ?

foreach(QString str, listofstrings)
{
    //code
}

o

int count = listofstrings.count();
QString str = QString();
for(int i=0;i<count;i++)
{
    str = listofstrings.at(i);
    //Code
}

7 votes

Une remarque rapide : si vous ne prévoyez pas de modifier la variable de la boucle foreach, vous devriez utiliser une const QString& à la place - cela a également des implications sur la vitesse.

0 votes

Voici une explication de la raison pour laquelle vous devez faire attention à inclure la const : labs.qt.nokia.com/2009/01/23/iterating-efficiently

1 votes

Le complément important à cette question est que vous ne devez jamais utiliser Qt foreach pour les conteneurs non Qt, il est fort probable qu'une copie profonde sera effectuée et c'est ce que vous ne voulez pas, même sans le profiler au préalable.

4voto

jalf Points 142628

Tout d'abord, je suis tout à fait d'accord avec la réponse "ça n'a pas d'importance". Choisissez la solution la plus propre, et optimisez si cela devient un problème.

Mais une autre façon de voir les choses est que, souvent, la solution la plus rapide est celle qui décrit le plus précisément votre intention. Dans ce cas, le foreach de QT indique que vous souhaitez appliquer une action à chaque élément du conteneur.

Une simple boucle for dit que vous souhaitez un compteur i . Vous voulez ajouter de façon répétée un à cette valeur i, et tant qu'elle est inférieure au nombre d'éléments du conteneur, vous souhaitez effectuer une action quelconque.

En d'autres termes, la simple boucle for spécifie trop le problème. Elle ajoute beaucoup d'exigences qui ne font pas partie de ce que vous essayez de faire. Vous ne devez pas soins sur le compteur de la boucle. Mais dès que vous écrivez une boucle for, il doit être là.

D'autre part, les gens de QT n'ont fait aucune promesse supplémentaire qui pourrait affecter les performances. Ils garantissent simplement d'itérer à travers le conteneur et d'appliquer une action à chacun.

En d'autres termes, la solution la plus propre et la plus élégante est souvent aussi la plus rapide.

3voto

justinhj Points 5060

Le foreach de Qt a une syntaxe plus claire pour la boucle for, à mon avis, donc il est meilleur dans ce sens. En ce qui concerne les performances, je doute qu'il y ait quelque chose à y gagner.

Vous pouvez envisager d'utiliser le BOOST_FOREACH à la place, car il s'agit d'une boucle for fantaisie bien pensée, et elle est portable (et on peut supposer qu'elle fera un jour son chemin vers le C++ et qu'elle est également à l'épreuve du futur).

3voto

Bilderbikkel Points 21

Vous trouverez une étude comparative, et ses résultats, sur ce sujet à l'adresse suivante http://richelbilderbeek.nl/CppExerciseAddOneAnswer.htm

À mon avis (et celui de beaucoup d'autres personnes ici), cela n'a pas d'importance (c'est-à-dire la vitesse).

Mais n'hésitez pas à tirer vos propres conclusions.

2voto

Foredecker Points 5784

Pour les petites collections, cela devrait avoir de l'importance et foreach a tendance à être plus clair.

Cependant, pour les grandes collections, for commencera à battre foreach à un moment donné. (en supposant que l'opérateur 'at()' soit efficace.

Si c'est vraiment important (et je suppose que ça l'est puisque vous le demandez), la meilleure chose à faire est de le mesurer. Un profileur devrait faire l'affaire, ou vous pourriez construire une version de test avec une certaine instrumentation.

0voto

Darren Clark Points 1489

Je m'attendrais à ce que foreach fonctionne nominalement plus vite dans certains cas, et à peu près pareil dans d'autres, sauf dans les cas où les éléments sont un tableau réel, auquel cas la différence de performance est négligeable.

Si elle est mise en œuvre au-dessus d'un énumérateur, elle mai être plus efficace qu'une indexation directe, selon l'implémentation. Il est peu probable qu'elle soit moins efficace. Par exemple, si quelqu'un expose un arbre équilibré comme étant à la fois indexable et énumérable, alors foreach sera relativement plus rapide. C'est parce que chaque index devra trouver indépendamment l'élément référencé, tandis qu'un énumérateur a le contexte du nœud actuel pour naviguer plus efficacement vers le prochain ont.

Si vous avez un tableau réel, alors cela dépend de l'implémentation du langage et de la classe si foreach sera plus rapide que for.

Si l'indexation est un décalage de mémoire littéral (comme en C++), alors for devrait être légèrement plus rapide puisque vous évitez un appel de fonction. Si l'indexation est une indirection comme un appel, alors cela devrait être la même chose.

Tout cela étant dit... je trouve difficile de trouver un cas de généralisation ici. C'est le dernier type d'optimisation que vous devriez rechercher, même s'il y a un problème de performance dans votre application. Si vous avez un problème de performance qui peut être résolu en changeant la façon dont vous itérez, vous n'avez pas vraiment un problème de performance. Vous avez un BUT, parce que quelqu'un a écrit soit un itérateur vraiment mauvais, soit un indexeur vraiment mauvais.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X