[Java lista] for: ++i vagy i++

istvan.ketler at lhsystems.com istvan.ketler at lhsystems.com
2009. Feb. 9., H, 12:15:04 CET


Ebben a konkrét esetben viszont t1 és t2 nem ugyanazt végzi el, mert az egyik alulról felfelé, a másik felülről lefelé megy végig a "műveletek tömbjén". Mondjuk egy tabbed pane fülekkel való feltöltése például leginkább csak az egyik irányba működik, a másik kód ott eleve hibás (nem adhatsz hozzá tizedik fület, ha még első sincs). Adatbázisba irkálás esetén sem feltétlenül mindegy, mindenféle tranzakciók, egyebek másként működhetnek. Például ezért is van az, hogy az optimalizálás tervezési kérdés, nem pedig kódolási.

Egyébként:

int i = -1;
while (i < n - 1) {
	i++;
	// do your stuff here
}

végső soron megegyezik a for ciklussal:

for (int i = 0;  i < n;  i++) {
	// do your stuff here
}

A bájtkód mégsem lehet ugyanaz, mert az első esetben az i értéke a ciklus után is látszik, míg a másik esetén nem. Ez akkor is így van, ha az i változó "cikluselhagyó" értékét nem használom. Viszont ezt az okos optimalizáló észreveheti, és máris lehetne ugyanaz a bájtkód. Ehhez persze az is kell, hogy észrevegye, hogy a legelső utasítás az i++, és i értékét előtte nem használom.

Visszatérve a kályhához, azt viszont mindenképpen elvárom egy optimalizálótól, hogy a magányos i++ és ++i utasítást ugyanannak fordítsa (magányos, ha nem használom a kifejezés értékét, csak növelni akarom az i-t). Szóval ahol szabadon választhatom ki, pl. a for ciklus végén, már csak ezért is tökmindegy, ha meg az értéke is kell, akkor meg úgysem mindegy (hiszen más az érték).

Érdekesség: miért -1 a kezdőérték a while-ban? Azért, mert így a "do your stuff here"-ben kiadott "continue" jól működik, hiszen a növelés a következő ciklus legelső utasítása lesz, nem pedig az adott ciklus legvégén növelődik (vagyis tényleg független a ciklusmag többi részétől a viselkedés, ergo valóban pontosan kiváltja a for-t). Az n-1 műveletet pedig az optimalizáló úgyis csak egyszer végezteti el, nem pedig minden lefutásnál. Ez már 25 éve is így volt a Unix v7 C v7 fordítójával (de talán már a v6 is tudta). Baj viszont, hogy a kód kevésbé olvasható (nem szívesen lennék annyira elvetemült, hogy így váltsam ki a for ciklust), így mondjuk egyetemi vizsgakérdésnek pont megfelel. ;)

Mellesleg érdekesség2: a v6 C fordító esetén a return(kifejezés) nem függvényból való visszatérésként értelmeződött, hanem meghívta a "return" nevű globális függvényt (ami persze nem létezett, így linkeléskor hiba volt). Ha tettél szóközt, vagy elhagytad a zárójelet, akkor jól működött. D.M.Ritchie is írhat bugot... :) A v7-ben már ki volt javítva. Gondolom, előbb nézte, hogy függvényhívás pattern-e, mint hogy kulcsszó-e.

Üdvözlettel,

Iván

István Ketler
Project Coordinator
 
Lufthansa Systems Hungaria Kft.
Airline Management Solutions
Schedule & Revenue Management
Alkotás u. 53.
1123 Budapest
Hungary
 
Tel: +36 1 887-2815
Fax: +36 1 887-2977
 
Room: MOM Park, Building A, Room 556
 
e-mail: istvan.ketler at lhsystems.com
Internet: www.LHsystems.hu
 

> 
 
Sitz der Gesellschaft / Corporate Headquarters: Lufthansa Systems Hungaria Kft, Budapest, Fövarosi Birosag 01-09-463417
Geschaeftsfuehrung / Management Board: Monika Houck

-----Original Message-----

> From: javalist-bounces at javagrund.hu 
> [mailto:javalist-bounces at javagrund.hu] On Behalf Of biziclop
> Sent: Monday, February 09, 2009 11:41 AM
> To: javalist at javagrund.hu
> Subject: Re: [Java lista] for: ++i vagy i++
> 
> 2009/2/9 Andras Suller <suller.andras at gmail.com>:
> > Varjasi Norbert <varjasin at sze.hu> írta (2009. február 8. 22:12):
> >> Ha már optimalizálni szeretnénk, akkor egy újabb adalék, amelyet 
> >> nevezhetnénk a beágyazott programozók kedvenc ciklusának is:
> >> i++, vagy i-- ?
> >> Kérdés miért jobb a t2-es hívás, mint a t1? (Iterációnként 
> legalább 
> >> egy belső hívással.) void t1(int n){
> >>        for (int i=0; i<n; i++){
> >>            muvelet(i);
> >>        }
> >>    }
> >> void t2(int n){
> >>        for (int i=n; i>0; i--){
> >>            muvelet(i);
> >>        }
> >> }
> >
> > Mivel a muvelet felhasználja az i értékét, így a két megoldás 
> > szerintem nem ekvivalens. Optimalizáláskor nem biztos, hogy 
> az egyiket 
> > a másikba át lehet alakítani, ez feladatfüggő. Már csak 
> azért is, mert 
> > az i értékkészlete a két függvény esetén nem ugyanaz :)
> >
> > psmith
> 
> Szerintem viszonylag jogosan elvarhato, hogy ha a ket kod 
> pontosan ugyanazt csinalja, akkor ugyanaz legyen a 
> bytecode-ja is. (Tekintve hogy rendkivul egyszeru esetrol van szo.)
> 
> Es megforditva: ha kulonbozo bytecode-ot akarsz latni, akkor 
> ugy kell hasznalnod a ket operatort, hogy kulonbozo mukodest 
> vonjon maga utan.
> 
> Vagy csak en vagyok ennyire egyszeru?
> 
> lsp
> _______________________________________________
> Javalist mailing list
> Javalist at javagrund.hu
> http://javagrund.hu/mailman/listinfo/javalist
> 


További információk a(z) Javalist levelezőlistáról