Tout le monde aime ses micro-optimisations, mais cela ne ferait pas de différence à mon avis. J'ai compilé les deux variantes avec g++ on pour les processeurs Intel sans aucune optimisation fantaisiste et les résultats sont les suivants
for(int i = 0; i < 5; i++)
movl $0, -12(%ebp)
jmp L2
L3:
leal -12(%ebp), %eax
incl (%eax)
L2:
cmpl $4, -12(%ebp)
jle L3
for(int i = 0; i != 5; ++i)
movl $0, -12(%ebp)
jmp L7
L8:
leal -12(%ebp), %eax
incl (%eax)
L7:
cmpl $5, -12(%ebp)
jne L8
Creo que jle
y jne
devrait se traduire par des instructions aussi rapides sur la plupart des architectures. Donc, pour les performances, vous ne devriez pas faire de distinction entre les deux. En général, je suis d'accord pour dire que la première est un peu plus sûre et je pense aussi qu'elle est plus courante.
EDIT (2 ans plus tard) : Étant donné que ce fil de discussion a de nouveau reçu beaucoup d'attention récemment, je voudrais ajouter qu'il sera difficile de répondre à cette question de manière générale. Les versions du code qui sont les plus efficaces ne sont pas spécifiquement définies par la norme Norme C [PDF] (il en va de même pour le C++ et probablement aussi pour le C#).
Section 5.1.2.3 Exécution du programme
§1 Les descriptions sémantiques de la présente Norme internationale décrivent le comportement d'une machine abstraite dans laquelle les questions d'optimisation ne sont pas pertinentes.
Mais il est raisonnable de supposer qu'un compilateur moderne produira un code tout aussi efficace et je pense que dans de très rares cas seulement le loop-test y el expression de comptage être le goulot d'étranglement d'une boucle for.
Quant au goût, j'écris
for(int i = 0; i < 5; ++i)
20 votes
Je dirais que pour la plupart des compilateurs et des processeurs, votre boucle n'est pas plus rapide du tout. Utilisez la première version pour que les autres programmeurs puissent comprendre la boucle plus facilement. Maintenant, en comptant jusqu'à zéro sera vous aider sur certains processeurs, mais vous devez vous demander si cela en vaut la peine.
2 votes
Quelle est la raison pour laquelle vous pensez qu'il est plus efficace ? Vous parlez en termes de temps de fonctionnement, n'est-ce pas ?
0 votes
Oui, courir serait plus rapide je crois mais je peux me tromper.
5 votes
Dans la plupart des langages, la première forme est plus courante (et il n'y a pas de différence en termes d'efficacité). En C++, la deuxième forme est plus courante, car elle peut être utilisée avec les itérateurs forward/bidirectionnels ainsi qu'avec les itérateurs à accès aléatoire, alors que la deuxième forme n'est utilisable qu'avec les itérateurs à accès aléatoire.
0 votes
En fait (notamment sur le Z80) faire un
!=
est plus rapide (et plus petite) que de faire une comparaison de type<
comparaison sur certaines plateformes. À moins que vous n'écriviez un code extrêmement critique, efforcez-vous de le rendre lisible.0 votes
Le décompte peut être meilleur sur la série 68000 grâce à l'instruction dbra. C'est aussi mieux pour JavaScript. Mais je dirais toujours qu'il faut respecter la convention, sauf si vous avez une bonne raison de ne pas le faire.
1 votes
Je croyais que si je mangeais mes épinards, je deviendrais une sorte de machine à botter les fesses. Il s'avère que je me suis trompé :) Faites-en le profil et découvrez-le.
2 votes
@Earlz Il n'écrit pas de code assembleur Z80 pourtant. Si une comparaison est plus rapide que l'autre, le compilateur utilisera probablement la comparaison la plus rapide, indépendamment de ce qu'il code.
0 votes
@DavidSchwartz cela dépend vraiment du compilateur, si le compilateur optimise le code alors il n'y a pas besoin de s'inquiéter de la façon dont cela se passe, mais si le compilateur n'optimise pas le code alors il est utile de savoir quel effet les deux différentes options auraient sur le code compilé. cela dépend vraiment du compilateur.
3 votes
@harryovers quel détail vous manque-t-il dans les réponses actuelles ? La réponse de Lucas semble très détaillée.
2 votes
@harryovers Si la performance de la boucle est que important, vous ne cherchez pas la construction théoriquement la meilleure. Au lieu de cela, vous testez plusieurs versions avec des données du monde réel et le compilateur cible et vous utilisez la plus rapide.
0 votes
@TimothyJones La réponse de Lucas ne montre que les résultats d'un seul compilateur, j'ai mis un bounty sur la question pour essayer d'avoir l'avis d'autres personnes car il semble qu'il n'y ait pas de réponse unique car cela dépend du compilateur, la question concerne également le format et non l'exemple exact (( ! = ou <) et (++i ou i++)) comme le souligne RenanGreinert "Il n'y a pas de différence pour cela lorsque vous travaillez avec des types de base, mais lorsque vous utilisez un itérateur STL, la préincrémentation est plus efficace" l'argument != / < est une question de maintenance du code, de compilateur, de processeur et de l'objet utilisé.
0 votes
@TomekSzpakowicz La question porte davantage sur les meilleures pratiques que sur la résolution d'un problème précis.
1 votes
Ce pré-incrément semble confus.
1 votes
La réponse de @harryovers Lucas montre que la sortie du compilateur n'est pas pertinente pour la question de savoir lequel utiliser, car les compilateurs sont suffisamment intelligents pour produire un code raisonnablement efficace dans les deux cas. Ce qui compte, c'est la cohérence, la lisibilité, la compréhensibilité et la correction de votre code.
1 votes
Voir aussi "Pourquoi != est utilisé avec les itérateurs ?" où j'explique pourquoi
!=
est toujours préférable pour les boucles qui itèrent sur tous les éléments d'une séquence en C++.2 votes
Pourquoi ne pas le diviser en
<
vs!=
y++i
vsi++
? De nombreuses réponses semblent répondre à l'une ou l'autre de ces questions, mais pas aux deux.0 votes
Downvoting de la question en raison de la publication d'une prime sur une question qui devrait être un wiki communautaire (car il n'y aura pas de meilleure réponse globale, parce que la question mélange de manière inappropriée la micro-optimisation des performances de C++, C et C#).
0 votes
@AntonGolov vous avez raison c'est pourquoi il est si difficile de sélectionner une seule bonne réponse.
0 votes
@gnat pas vraiment un doublon, je dirais que l'autre couvre beaucoup moins que ce fil. pourquoi dites-vous que c'est un doublon ?
0 votes
Je suis d'accord pour dire que l'autre question est plus ciblée. Je pense qu'être moins large dans ce cas, cela en fait une bonne cible dupliquée (il serait probablement encore mieux de fermer cette question en tant que duplicata de plusieurs cibles mieux ciblées, mais malheureusement, le système ne dispose pas d'une telle fonctionnalité).
0 votes
Je dirais que les deux sont "trop broards" mais pas des doublons.
0 votes
@Deduplicator Pour expliquer la raison de mon retour en arrière : Je pense qu'en ajoutant la phrase "Y a-t-il d'autres bonnes raisons ?" vous changez/étendez le champ/le centre de la question, alors que les réponses ont déjà été données il y a des années. Et en effet, il est nécessaire d'ajouter cette question pour pouvoir noter les réponses. la version récente comme dupliqué : Je ne pense pas que ce soit une procédure correcte.
0 votes
@Antonio : Les réponses à cette question ne se limitent pas aux performances, elles adoptent une vision plus large, même si une grande partie de l'argent n'est pas disponible. strict La lecture de la question n'aurait peut-être pas exigé cela. Si vous pensez que j'ai été un peu maladroit en reformulant la question, cela arrive. Et oui, ce sont des doublons.
0 votes
@Deduplicator Une fois exclu le point de vue de l'efficacité (point central de cette question), les réponses à la nouvelle question sont bien plus profondes que celles données pour celle-ci. Je pense qu'elles sont probablement un bon candidat pour une fusion, qu'en pensez-vous ?
0 votes
@Deduplicator Ils vont plus loin sur certains aspects.
0 votes
@Deduplicator Une réponse assez originale se trouve ici stackoverflow.com/a/31465421/2436175 . Et ceci est également important stackoverflow.com/a/31474750/2436175
0 votes
@Antonio Ok. Assurez-vous de mettre ces deux-là en évidence lorsque vous les signalez pour les fusionner, et donnez un résumé très concis de ce qu'ils ajoutent.