grundlegendes

Status
Nicht offen für weitere Antworten.

dronus

Mitglied
Hallo.
Was ist schneller:

1.
Code:
for (int i=0; i<n; i++){
	final int j=i+irgendwas;
	tuEtwasMitJ(j);
}

oder

2.
Code:
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?
 

Luma

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

jptc.org

Bekanntes Mitglied
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

Bekanntes Mitglied
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

Gesperrter Benutzer
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

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

Bzw, da is ja net soviel unterschied..
 

bambi

Bekanntes Mitglied
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

Mitglied
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

Bekanntes Mitglied
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:
Code:
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

Top Contributor
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:
Code:
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:

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

thE_29

Top Contributor
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

Gesperrter Benutzer
wenn ich mal zeit habe teste ich das auch mal
der code
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"...
 
B

Bleiglanz2

Gast
Es ist zwar wie erwartet völlig witzlos, aber ich habs doch mal wieder probiert....
Code:
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 :)

Code:
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
 
G

Guest

Gast
Hallo!

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

Gruß Tom
 
B

Bone

Gast
Hm... wie darf ich mir das vorstellen?

Ich habe folgendes:
Code:
final int i;
i = 0;
i = 2; // Fehler

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

Roar

Gast
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.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Grundlegendes zu JAVA_HOME und PATH Allgemeine Java-Themen 9

Ähnliche Java Themen


Oben