# grundlegendes



## dronus (4. Mrz 2005)

Hallo.
Was ist schneller:

1.

```
for (int i=0; i<n; i++){
	final int j=i+irgendwas;
	tuEtwasMitJ(j);
}
```

oder 

2.

```
int j;
for (int i=0; i<n; i++){
	j=i+irgendwas;
	tuEtwasMitJ(j);
}
```

?

Altmodisch gesehen ist 2. schneller... aber die VM soll ja recht auf Stack-Arbeit stehen soweit ich weiss?


----------



## Bleiglanz (4. Mrz 2005)

probiers halt aus, aber lies vorher

http://www-128.ibm.com/developerworks/java/library/j-jtp02225.html


----------



## Luma (7. Mrz 2005)

Naja Stacks und deren Methoden sind ja alle als synchronized markiert...


----------



## jptc.org (8. Mrz 2005)

Prinzipiel ist die 2. variante schneller, jedoch sollte der Unterschied sich bei den primitiven datentypen im rahmen halten (wird wohl nicht wirklich feststellbar sein). Wenn Dein j aber zu einem Object wird, dann solltest Du eigentlich immer die 2. variante nutzen, da die erste immer wieder neue objekte anlegen und aufräumen muss.

http://www.java-performance-portal.org


----------



## TRunKX (16. Mrz 2005)

1. schneller!!!

Begründung:

1. Habe einen Test geschrieben der mir das verraten hat 

2. Java VM 

3. lest mal fachbücher zu dem Thema!


----------



## Bleiglanz (16. Mrz 2005)

das ist keine begründung, sondern arrogantes gefasel



			
				TRunKX hat gesagt.:
			
		

> 1. schneller!!!
> Begründung:
> 1. Habe einen Test geschrieben der mir das verraten hat
> 2. Java VM
> 3. lest mal fachbücher zu dem Thema!



zu 1) zeig mal her, so ein microbenchmark ist sehr sehr schwierig, also interessieren micht konkrete umsetzungen immer

zu 2) ja, sowas gibts, und?

zu 3)  komische begründung?


----------



## thE_29 (16. Mrz 2005)

Mich würd interessieren warum 2 überhaupt schneller sein sollte??

Bzw, da is ja net soviel unterschied..


----------



## Bleiglanz (16. Mrz 2005)

2 is 1% schneller, weil nur einmal ein int auf dem Heap erzeugt wird -vermute ich mal


----------



## bambi (16. Mrz 2005)

Also bei uns wird super-streng drauf geachtet, dass wir an sowas wie 1. gar nicht denken! Ist meines Wissens auch
langsamer, wenn in der Schleife jedes mal ein neues Objekt erzeugt wird...
Der Test wuerde mich echt mal interessieren. Her damit...  :wink:


----------



## dronus (16. Mrz 2005)

ich kann mir durchaus vosrtellen, das auch 1. schneller sein kann.
immerhin muss bei jedem durchlauf zwar ein int auf den stack, dieser ist aber gleich wieder runter, read-only und wird nach der schleife sterben. daher kann der hochgradig optimiert werden, z.b. nie im speicher, nur im prozessoregister verarbeitet werden..

bei 2. müsste der compiler sicher sein, das j nach der schleife nie wieder genutzt wird, sonst wird er es in jedem durchaluf in den speicher schreiben müssen. ich glaube nicht, das er so "klug" ist, daher wird in diesem code j dann wohl auf dem heap leben müssen.

achja, @ luma: ich meinte mit stack den internen stack-arbeitsspeicher der VM, nicht objekte dieser klassen. der stack in der VM ist sicher nicht synchronized  wär sonst etwas langsam, und zwar alles...

mfg
Paul


----------



## bambi (16. Mrz 2005)

Also bevor jemand frage: Ja, mir iss langweilig...
Also ich hab's auch mal getestet - mit ein paar mehr Variablen, damits auch ein wenig mehr "Spass" macht - na gut...
aber man bekommt wenigstens ein paar bessere Werte. Also mein ergebnis:

```
Loop 1 ist in etwa 35 - 40 % am schnellsten
Loop 2 ist in etwa 45 - 50 % am schnellsten
und ansonsten ist's eben gleich...
```

Ich poste meinen Code einfach mal ins Codegeschnipsel - falls mir wer nicht glauben mag - oder jemandem auch 
sooo langweilig iss...  :wink:


----------



## Sky (17. Mrz 2005)

bambi hat gesagt.:
			
		

> Also bevor jemand frage: Ja, mir iss langweilig...
> Also ich hab's auch mal getestet - mit ein paar mehr Variablen, damits auch ein wenig mehr "Spass" macht - na gut...
> aber man bekommt wenigstens ein paar bessere Werte. Also mein ergebnis:
> 
> ...



Hast Du eine IDE benutzt oder hast Du per Konsole gestartet?


----------



## thE_29 (17. Mrz 2005)

http://www.java-forum.org/de/viewtopic.php?t=15404

Ähm, du solltest aber final int und nicht int nehmen!

Da isn unterschied!!


----------



## Sky (17. Mrz 2005)

thE_29 hat gesagt.:
			
		

> http://www.java-forum.org/de/viewtopic.php?t=15404



Hatte ich auch schon gesehen...

Meine Frage wegen IDE oder Konsole kam auf, wegen der Messgenauigkeit...


----------



## thE_29 (17. Mrz 2005)

Also schau hin nochmal, ich hab auch ein paar Tests gemacht und man kann net wirklich zu einem eindeutigen Ergebnis kommen, außer dass das final irgendwie sogar langsamer ist!


----------



## Bleiglanz (17. Mrz 2005)

wenn ich mal zeit habe teste ich das auch mal
der code

```
int j;
for (int i=0; i<n; i++){
   j=i+irgendwas;
   tuEtwasMitJ(j);
}
```
ist auf jeden Fall zu vermeiden (egal was schneller ist), weil die Variabel j dabei ihren scope unnötig ausdehnt -> "bad smell"...


----------



## Bleiglanz2 (17. Mrz 2005)

Es ist zwar wie erwartet völlig witzlos, aber ich habs doch mal wieder probiert....

```
package test;

public class TestLoops {
    
    public static final int n=Integer.MAX_VALUE;
    
    public static final int irgendwas = 42;
    
    public static int seiteneffekthalter = 0;
    
    public static boolean seiteneffekt = false;
    
    public static void main(String[] a) {
        // warmup
        seiteneffekt=false;
        test();
        seiteneffekt=true;
        test();
        
        // messungen
        System.out.println("ohne seiteneffekt");
        seiteneffekt = false;
        for(int w=0;w<10;w++)
        {
            test();
        }
        System.out.println("mit seiteneffekt");
        seiteneffekt = true;
        for(int w=0;w<10;w++)
        {
            test();
        }
    }
    
    public static void test(){
               
        long start = System.currentTimeMillis();
        loop1();
        long stop1 = System.currentTimeMillis();
        loop2();
        long stop2 = System.currentTimeMillis();
        long time1 = stop1-start;
        long time2 = stop2-stop1;
        System.out.print("    Schleife1:"+time1);
        System.out.print(" Schleife2:"+time2);
        System.out.println(" S1/S2:"+(time1*1.0)/time2);
    }
    
    public static void loop1() {
        for (int i=0; i<n; i++){
            final int j=i+irgendwas;
            tuEtwasMitJ(j);
        }
    }
    
    public static void loop2() {
        int j;
        for (int i=0; i<n; i++){
            j=i+irgendwas;
            tuEtwasMitJ(j);
        }
    }
    
    public static void tuEtwasMitJ(int k) {
        k++;
        if(seiteneffekt) seiteneffekthalter = k;
    }
}
```

Das alles total fragil, tuEtwasMitJ beeinflusst die Messergebnisse EXTREM, sobald da irgendwas drin steht sieht das alles ganz anders aus. So wie die Ergebnisse sind, würde ich nicht sagen dass eine von beiden schneller ist...

Das einzige was ich daraus gelernt habe: auf einem 2.6GHz Duron kann man in 10 Sekunden von 0 bis Integer.MAX_VALUE iterieren 


```
run:
    Schleife1:9063 Schleife2:8843 S1/S2:1.024878434920276
    Schleife1:10688 Schleife2:10640 S1/S2:1.0045112781954888
ohne seiteneffekt
    Schleife1:9750 Schleife2:9860 S1/S2:0.9888438133874239
    Schleife1:9750 Schleife2:9859 S1/S2:0.9889441119789025
    Schleife1:9750 Schleife2:9844 S1/S2:0.9904510361641609
    Schleife1:9734 Schleife2:9875 S1/S2:0.9857215189873417
    Schleife1:9750 Schleife2:9860 S1/S2:0.9888438133874239
    Schleife1:9750 Schleife2:9859 S1/S2:0.9889441119789025
    Schleife1:9750 Schleife2:9859 S1/S2:0.9889441119789025
    Schleife1:9797 Schleife2:9828 S1/S2:0.9968457468457469
    Schleife1:9782 Schleife2:9812 S1/S2:0.996942519364044
    Schleife1:9797 Schleife2:10547 S1/S2:0.9288897316772542
mit seiteneffekt
    Schleife1:12453 Schleife2:10844 S1/S2:1.148376982663224
    Schleife1:10656 Schleife2:10625 S1/S2:1.0029176470588235
    Schleife1:10828 Schleife2:10797 S1/S2:1.002871167917014
    Schleife1:10859 Schleife2:10735 S1/S2:1.0115510013972986
    Schleife1:10765 Schleife2:10797 S1/S2:0.9970362137630824
    Schleife1:10922 Schleife2:11110 S1/S2:0.9830783078307831
    Schleife1:11531 Schleife2:10687 S1/S2:1.0789744549452607
    Schleife1:10907 Schleife2:10750 S1/S2:1.0146046511627906
    Schleife1:10750 Schleife2:10703 S1/S2:1.0043912921610763
    Schleife1:10812 Schleife2:10828 S1/S2:0.9985223494643517
```


----------



## bambi (17. Mrz 2005)

thE_29 hat gesagt.:
			
		

> Ähm, du solltest aber final int und nicht int nehmen! Da isn unterschied!!


Ich hab's mit final und ohne getestet. Da waren die Daten gleich... Kein sichtbarer Unterschied zumindest.


> Hast Du eine IDE benutzt oder hast Du per Konsole gestartet?


Ich hab's mit Eclipse getestet.


----------



## Guest (20. Apr 2005)

Hallo!

Das final bei lokalen Variablen fällt ja auch weg beim Compilieren ;-)

Gruß Tom


----------



## Bone (11. Sep 2005)

Hm... wie darf ich mir das vorstellen?

Ich habe folgendes:

```
final int i;
i = 0;
i = 2; // Fehler
```

Imo fällt das dann bei lokalen Variablen nicht weg  :bahnhof:


----------



## Roar (11. Sep 2005)

er sagte auch beim kopmilieren fällt es weg. ob eine lokale variable final ist oder nicht steht nich im bytecode, ist ja im endeffekt auch völlig irrelevant bei lokalen variablen.


----------

