Is er een prestatieverschil tussen i++ en ++i in C?

 C Programming >> C Programmeren >  >> C
Is er een prestatieverschil tussen i++ en ++i in C?

Managementsamenvatting:Nee.

i++ kan mogelijk langzamer zijn dan ++i , sinds de oude waarde van i moet misschien worden opgeslagen voor later gebruik, maar in de praktijk zullen alle moderne compilers dit weg optimaliseren.

We kunnen dit aantonen door naar de code voor deze functie te kijken, beide met ++i en i++ .

$ cat i++.c
extern void g(int i);
void f()
{
    int i;

    for (i = 0; i < 100; i++)
        g(i);

}

De bestanden zijn hetzelfde, behalve ++i en i++ :

$ diff i++.c ++i.c
6c6
<     for (i = 0; i < 100; i++)
---
>     for (i = 0; i < 100; ++i)

We compileren ze en krijgen ook de gegenereerde assembler:

$ gcc -c i++.c ++i.c
$ gcc -S i++.c ++i.c

En we kunnen zien dat zowel het gegenereerde object als de assembler-bestanden hetzelfde zijn.

$ md5 i++.s ++i.s
MD5 (i++.s) = 90f620dda862cd0205cd5db1f2c8c06e
MD5 (++i.s) = 90f620dda862cd0205cd5db1f2c8c06e

$ md5 *.o
MD5 (++i.o) = dd3ef1408d3a9e4287facccec53f7d22
MD5 (i++.o) = dd3ef1408d3a9e4287facccec53f7d22

Van efficiëntie versus intentie door Andrew Koenig:

En :

Dus als de resulterende waarde niet wordt gebruikt, zou ik ++i . gebruiken . Maar niet omdat het efficiënter is:omdat het mijn bedoeling correct weergeeft.


Een beter antwoord is dat ++i zal soms sneller zijn, maar nooit langzamer.

Iedereen lijkt aan te nemen dat i is een normaal ingebouwd type zoals int . In dit geval is er geen meetbaar verschil.

Maar als i is een complex type, dan vindt u misschien een meetbaar verschil. Voor i++ je moet een kopie van je klas maken voordat je deze verhoogt. Afhankelijk van wat er bij een kopie betrokken is, kan het inderdaad langzamer zijn sinds met ++it je kunt gewoon de uiteindelijke waarde retourneren.

Foo Foo::operator++()
{
  Foo oldFoo = *this; // copy existing value - could be slow
  // yadda yadda, do increment
  return oldFoo;
}

Een ander verschil is dat met ++i je hebt de mogelijkheid om een ​​referentie te retourneren in plaats van een waarde. Nogmaals, afhankelijk van wat er komt kijken bij het maken van een kopie van je object, kan dit langzamer zijn.

Een praktijkvoorbeeld van waar dit kan gebeuren, is het gebruik van iterators. Het is onwaarschijnlijk dat het kopiëren van een iterator een knelpunt is in uw toepassing, maar het is nog steeds een goede gewoonte om de gewoonte aan te nemen om ++i te gebruiken in plaats van i++ waar de uitkomst niet wordt beïnvloed.