For ciklus esetében léptető utasításnál a ++i miért gyorsabb, mint az i++?
Még az egyik tanárom mondta és valóban így van debugoltattam és ++i esetén <1ms
míg i++ esetén <2ms telt el.
De ez nem mindig alkalmazható, mivel i++ esetén csinál vizsgálatot hogy a ciklus utasítások alatt történt-e változás az i-vel míg a ++i nem <-- és emiatt nemvárt eredmények jöhetnek ??
Jó példát szeretnék látni hogy a ++i mikor nem jó.
Tehát ennél pl tökmindegy max gyorsaság szempontjából nem
int[] T = new int[10];
Random rnd = new Random();
for (int i = 0, n = T.Length; i < n; ++i)
T[i] = rnd.Next(100);
int a = 0, b = 0;
Itt nem mindegy:
a = ++b;
a = b++;
Azért gyorsabb mert a ++i növeli eggyel és azt adja vissza, míg a i++ eltárolja az értékét, növeli magát eggyel és az eltárolt értéket adja vissza.
Viszont Release módban minden valamire való fordító ugyan azt a kódot fogja a for ciklusnál generálni, mert nem használod a visszatérési értékét, tehát nem lesz gyorsabb a ++i.
Szerintem a tanárod félrebeszél, te pedig valamit nagyon benéztél, kizárt dolog hogy ms nagyságendű legyen bármelyik futáta, ez azt jelentené, hogy másodpercenként ezer db inkrementálást tudna végrehajtani a géped, gyakorlaitlag kHz-es proci sebességet jelent. (mondjuk mind2 helyen kisebb jelet irtal, a pár nanosec pedig tényleg kisebb mint 1 és 2 ms:))
Ha jól tippelek ez C# kód, kipróbáltam, és tök ugyanaz az IL kót lett belőle forditás után:
.method public hidebysig instance void a(int32 a) cil managed
{
.maxstack 2
.locals init (
[0] int32 num,
[1] bool flag)
L_0000: nop
L_0001: ldc.i4.0
L_0002: stloc.0
L_0003: br.s L_000b
L_0005: nop
L_0006: nop
L_0007: ldloc.0
L_0008: ldc.i4.1
L_0009: add
L_000a: stloc.0
L_000b: ldloc.0
L_000c: ldc.i4.s 10
L_000e: clt
L_0010: stloc.1
L_0011: ldloc.1
L_0012: brtrue.s L_0005
L_0014: ret
}
Ezt forditottam le:
public void a(int a)
{
for (int i = 0; i < 10; i++)
{
}
}
Ill ugyanez ++i-vel
Itt teljesen érthető, hogy miért
int i = 0;
while (i<10)
{
Console.WriteLine("i: " + (i++));
}
Kiíratja majd növel
VS
while (i<10)
{
Console.WriteLine("i: " + (++i));
}
Kiíratás előtt növel, majd a növeltet íratja ki
De a for ciklusnál az i++ vagy ++i a ciklusmag lefutása után kerül végrehajtásra, ergo tök mind1 hogy melyiket használjuk
Nem is tudom miért oktatják az i++ -osokat ha lassít
Azért mert nem lassít. Legalább is natív típusoknál nem.
Ha egy osztálynak van ++ operátora akkor nem mindegy, hiszen az i++ esetén az objektumról egy másolatot kell készítenie a programnak, míg a ++i esetén nem, bár ezt minden bizonnyal a fordító kioptimalizálja, erre nem kell számítani.
A te példádban teljesen mindegy hogy melyiket használod ugyan az lesz a kód. A régi C időkből visszamaradt programozói szokás az i++, ahol még nem voltak osztályok/objektumok, így nem számított hogy melyiket használtad.
Érezhető speedupot nem kellene érezned az i++ és a ++i között, de kérlek, vigyázz arra, hogy az i++ és a ++i KÜLÖNBÖZŐ MŰVELETEK:
i++:
Visszaadja i értékét, majd inkrementálja 1-gyel.
++i:
Inkrementálja i értékét, majd az inkrementált értéket adja vissza.
"Visszaadja i értékét, majd inkrementálja 1-gyel."
Ebből hiányzik egy lépés, és a sorrend is rossz.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!