Les opérateurs de pré et post incrémentation / décrémentation en C ++ ont-ils les mêmes performances dans une boucle? [dupliquer]

StackOverflow https://stackoverflow.com/questions/631506

  •  08-07-2019
  •  | 
  •  

Question

Considérez les deux exemples suivants.

class ClassOne
{
 //class definition is here
};

std::vector< ClassOne > myListOfObjects;

std::vector< ClassOne >::const_iterator iter = myListOfObjects.begin();

Example 1: 
for( ; iter < myListOfObjects.end(); **++iter**)
{
   //some operations
}

OR

Example 2: 
for( ; iter < myListOfObjects.end(); **iter++**)
{
   //some operations
}

Lequel est le plus rapide? ++ iter ou iter ++ dans le contexte de la boucle.

Raison Fermeture Fro:

Copié du message de Brian (pour rendre la question plus succincte).

Vous pouvez également essayer l'une de ces questions similaires: ici ou ici ou ici ou ici .

Était-ce utile?

La solution

Comme indiqué dans la cette réponse , avant est plus rapide. Ils ne sont identiques que lorsqu'il s'agit de primitives (int, char, etc.). Dans ce cas, ils appellent des opérateurs surchargés.

Autres conseils

Non, ils n'ont pas la même performance:

  • Postincrement va créer une copie, puis l'incrémenter, puis renvoyer la copie
  • Le préincrément incrémentera puis renverra l'original

Donc (sauf si vous manipulez des choses simples comme Ints), la préincrémentation est plus rapide.

Cela dépend. Dans un compilateur naïf, la préincrémentation sera plus rapide. En pseudocode, voici ce que chacun d'eux fait:

preincrement() {
  val = val + 1;
  return val;
}

postincrement() {
 tmp = val; // take a temporary copy of the old value
 val = val + 1;
 return tmp;
}

En pratique, le compilateur va souvent transformer un post-incrément en pré-incrémentation s’il peut s’en tirer. Mais pour les types complexes, il peut ne pas être capable de le faire. En règle générale, utilisez preincrement chaque fois que vous le pouvez et utilisez postincrmenet lorsque vous avez besoin de la sémantique spécifique de cette opération.

Lorsqu'il s'agit de types non primitifs: ++ iter sera toujours plus efficace.

La raison pour laquelle ++ iter est plus efficace dépend du travail que chacun doit effectuer pour obtenir sa valeur de retour. Que la valeur de retour soit réellement utilisée ou non importe peu.

La différence:

  • ++ iter renvoie une référence à elle-même . Aucune copie temporaire n'est donc nécessaire. (incrémenter, renvoyer la référence à sa propre valeur)

  • iter ++ renvoie une copie temporaire de la variable (crée une variable de temp avec l'ancienne valeur, incrémente, renvoie une variable de temp)

    _Myt _Tmp = *this;
    ++*this;
    return (_Tmp);
    

Vous pouvez également essayer l'une de ces questions similaires: ici ou ici ou ici ou ici . Cependant, ils ne sont pas exactement les mêmes car ils ne s'appliquent pas aux itérateurs.

Je suis presque sûr qu'ils se réduisent à la même chose dans le code machine, mais dans un ordre différent. Je dirais qu'ils sont les mêmes, mais je vous recommanderais d'écrire une application de test rapide pour vérifier.

La pré-incrémentation est, en général, préférable, à condition que vous n'ayez pas un besoin spécifique de post-incrémentation.

Cependant, ceci est une chose spécifique au compilateur. La plupart des compilateurs modernes créeront moins d'opérations pour une notation de préfixe. Avec les surcharges de méthodes de classe, cela n’obtient pas toujours une optimisation, car cela dépend de la manière dont la classe est implémentée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top