Ist das ein legitimer Test?

Willibergi

Mitglied
Ich wollte mal testen, wie viel Zeitverlust ein else continue; in einer for-Schleife mit sich bringt.

Ich habe dazu folgendes Programm geschrieben:
Java:
package programs;

import java.time.Duration;
import java.time.Instant;

public class LaufzeitTest {

    public static void main(String[] args){

        int a = 0, b = 0;
        int limit = 2_000_000_000;

        Instant i1 = Instant.now();

        for(int i=0; i < limit; i++){

            if(i%2 == 0) a++;
            else continue;

        }

        Instant i2 = Instant.now();
        a = 0;
        Instant i3 = Instant.now();

        for (int i=0; i < limit; i++) {

            if(i%2 == 0) a++;

        }

        Instant i4 = Instant.now();

        Duration dur1 = Duration.between(i1, i2);
        Duration dur2 = Duration.between(i3, i4);

        double d1 = Double.parseDouble(dur1.toString().substring(3, dur1.toString().length()-1));
        double d2 = Double.parseDouble(dur2.toString().substring(3, dur2.toString().length()-1));

        System.out.printf("Mit \"else continue;\": %fs%nOhne \"else continue;\": %fs%nDifferenz: %fs%n =>Um %f%% schneller!", d1, d2, d2-d1, (d2-d1)/d2*100);

    }

}

Meistens ist die Schleife ohne else continue; um ca. eine halbe Sekunde also um 50-60% schneller als die mit.

Nur bin ich mir nicht ganz sicher, ob das alles stimmt.

Ich meine, 50-60% ist schon richtig viel - nur dafür, dass die Schleife sowieso das tut was sie auch sonst täte, oder?

Drum wollte ich hier noch mal ein paar Profis drüberschauen lassen, ob das alles stimmt und ob damit auch mein Ergebnis stimmt.

Danke schonmal im Voraus. :)
 

Flown

Administrator
Mitarbeiter
Definitiv ist das kein gelungener Benchmarktest. Benutz doch Microbenchmark-Tools die dir das alles abnehmen, denn meistens misst du JVM Aktivitäten wie JIT/GC/etc...
Auf SO sind hier Tutorials wie das am besten gemacht wird.

Ich nutz für sowas immer JMH.
Code würde dann so aussehen:
Java:
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;

@Fork(3)
@BenchmarkMode(Mode.AverageTime)
@Measurement(iterations = 10, timeUnit = TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
@Threads(1)
@Warmup(iterations = 5, timeUnit = TimeUnit.NANOSECONDS)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {
 
  private final int LIMIT = 2_000_000_000;
 
  @Benchmark
  public int forContinue() {
    int a = 0;
    for (int i = 0; i < LIMIT; i++) {
      if (i % 2 == 0) {
        a++;
      } else {
        continue;
      }
     
    }
    return a;
  }
 
  @Benchmark
  public int forWOContinue() {
    int a = 0;
    for (int i = 0; i < LIMIT; i++) {
      if (i % 2 == 0) {
        a++;
      }
    }
    return a;
  }
}
und das Ergebnis:
Code:
Benchmark                  Mode  Cnt           Score         Error  Units
MyBenchmark.forContinue    avgt   30  1387601172,333 ± 6900383,114  ns/op
MyBenchmark.forWOContinue  avgt   30  1375414436,200 ± 6594290,245  ns/op
Interpretation: Beide Arten sind gleichwertig und es gibt kaum bis keinen Unterschied.
 

Meniskusschaden

Top Contributor
Ich habe mir mal den Bytecode angesehen. Das bestätigt das Ergebnis von @Flown. Hier ist der Bytecode der ersten Schleife:
Code:
     12  iconst_0
     13  istore 5 [i]
     15  goto 31
     18  iload 5 [i]
     20  iconst_2
     21  irem
     22  ifne 28
     25  iinc 1 1 [a]
     28  iinc 5 1 [i]
     31  iload 5 [i]
     33  iload_3 [limit]
     34  if_icmplt 18
Und hier der Bytecode der zweiten Schleife:
Code:
     49  iconst_0
     50  istore 7 [i]
     52  goto 68
     55  iload 7 [i]
     57  iconst_2
     58  irem
     59  ifne 65
     62  iinc 1 1 [a]
     65  iinc 7 1 [i]
     68  iload 7 [i]
     70  iload_3 [limit]
     71  if_icmplt 55
Es gibt offenbar keinen strukturellen Unterschied. Nur Zeilennummern und Variablen weichen logischerweise voneinander ab. Der Compiler optimiert den überflüssigen else-Zweig offenbar weg.
Zur Info noch der vollständige Bytecode:
Code:
// Compiled from LaufzeitTest.java (version 1.8 : 52.0, super bit)
public class programs.LaufzeitTest {

  // Method descriptor #6 ()V
  // Stack: 1, Locals: 1
  public LaufzeitTest();
    0  aload_0 [this]
    1  invokespecial java.lang.Object() [8]
    4  return
      Line numbers:
        [pc: 0, line: 6]
      Local variable table:
        [pc: 0, pc: 5] local: this index: 0 type: programs.LaufzeitTest

  // Method descriptor #15 ([Ljava/lang/String;)V
  // Stack: 9, Locals: 14
  public static void main(java.lang.String[] args);
      0  iconst_0
      1  istore_1 [a]
      2  iconst_0
      3  istore_2 [b]
      4  ldc <Integer 2000000000> [16]
      6  istore_3 [limit]
      7  invokestatic java.time.Instant.now() : java.time.Instant [17]
     10  astore 4 [i1]
     12  iconst_0
     13  istore 5 [i]
     15  goto 31
     18  iload 5 [i]
     20  iconst_2
     21  irem
     22  ifne 28
     25  iinc 1 1 [a]
     28  iinc 5 1 [i]
     31  iload 5 [i]
     33  iload_3 [limit]
     34  if_icmplt 18
     37  invokestatic java.time.Instant.now() : java.time.Instant [17]
     40  astore 5 [i2]
     42  iconst_0
     43  istore_1 [a]
     44  invokestatic java.time.Instant.now() : java.time.Instant [17]
     47  astore 6 [i3]
     49  iconst_0
     50  istore 7 [i]
     52  goto 68
     55  iload 7 [i]
     57  iconst_2
     58  irem
     59  ifne 65
     62  iinc 1 1 [a]
     65  iinc 7 1 [i]
     68  iload 7 [i]
     70  iload_3 [limit]
     71  if_icmplt 55
     74  invokestatic java.time.Instant.now() : java.time.Instant [17]
     77  astore 7 [i4]
     79  aload 4 [i1]
     81  aload 5 [i2]
     83  invokestatic java.time.Duration.between(java.time.temporal.Temporal, java.time.temporal.Temporal) : java.time.Duration [23]
     86  astore 8 [dur1]
     88  aload 6 [i3]
     90  aload 7 [i4]
     92  invokestatic java.time.Duration.between(java.time.temporal.Temporal, java.time.temporal.Temporal) : java.time.Duration [23]
     95  astore 9 [dur2]
     97  aload 8 [dur1]
     99  invokevirtual java.time.Duration.toString() : java.lang.String [29]
    102  iconst_3
    103  aload 8 [dur1]
    105  invokevirtual java.time.Duration.toString() : java.lang.String [29]
    108  invokevirtual java.lang.String.length() : int [33]
    111  iconst_1
    112  isub
    113  invokevirtual java.lang.String.substring(int, int) : java.lang.String [39]
    116  invokestatic java.lang.Double.parseDouble(java.lang.String) : double [43]
    119  dstore 10 [d1]
    121  aload 9 [dur2]
    123  invokevirtual java.time.Duration.toString() : java.lang.String [29]
    126  iconst_3
    127  aload 9 [dur2]
    129  invokevirtual java.time.Duration.toString() : java.lang.String [29]
    132  invokevirtual java.lang.String.length() : int [33]
    135  iconst_1
    136  isub
    137  invokevirtual java.lang.String.substring(int, int) : java.lang.String [39]
    140  invokestatic java.lang.Double.parseDouble(java.lang.String) : double [43]
    143  dstore 12 [d2]
    145  getstatic java.lang.System.out : java.io.PrintStream [49]
    148  ldc <String "Mit \"else continue;\": %fs%nOhne \"else continue;\": %fs%nDifferenz: %fs%n =>Um %f%% schneller!"> [55]
    150  iconst_4
    151  anewarray java.lang.Object [3]
    154  dup
    155  iconst_0
    156  dload 10 [d1]
    158  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [57]
    161  aastore
    162  dup
    163  iconst_1
    164  dload 12 [d2]
    166  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [57]
    169  aastore
    170  dup
    171  iconst_2
    172  dload 12 [d2]
    174  dload 10 [d1]
    176  dsub
    177  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [57]
    180  aastore
    181  dup
    182  iconst_3
    183  dload 12 [d2]
    185  dload 10 [d1]
    187  dsub
    188  dload 12 [d2]
    190  ddiv
    191  ldc2_w <Double 100.0> [61]
    194  dmul
    195  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [57]
    198  aastore
    199  invokevirtual java.io.PrintStream.printf(java.lang.String, java.lang.Object[]) : java.io.PrintStream [63]
    202  pop
    203  return
      Line numbers:
        [pc: 0, line: 9]
        [pc: 4, line: 10]
        [pc: 7, line: 11]
        [pc: 12, line: 12]
        [pc: 18, line: 14]
        [pc: 28, line: 12]
        [pc: 37, line: 18]
        [pc: 42, line: 19]
        [pc: 44, line: 20]
        [pc: 49, line: 21]
        [pc: 55, line: 22]
        [pc: 65, line: 21]
        [pc: 74, line: 25]
        [pc: 79, line: 26]
        [pc: 88, line: 27]
        [pc: 97, line: 28]
        [pc: 121, line: 29]
        [pc: 145, line: 30]
        [pc: 203, line: 32]
      Local variable table:
        [pc: 0, pc: 204] local: args index: 0 type: java.lang.String[]
        [pc: 2, pc: 204] local: a index: 1 type: int
        [pc: 4, pc: 204] local: b index: 2 type: int
        [pc: 7, pc: 204] local: limit index: 3 type: int
        [pc: 12, pc: 204] local: i1 index: 4 type: java.time.Instant
        [pc: 15, pc: 37] local: i index: 5 type: int
        [pc: 42, pc: 204] local: i2 index: 5 type: java.time.Instant
        [pc: 49, pc: 204] local: i3 index: 6 type: java.time.Instant
        [pc: 52, pc: 74] local: i index: 7 type: int
        [pc: 79, pc: 204] local: i4 index: 7 type: java.time.Instant
        [pc: 88, pc: 204] local: dur1 index: 8 type: java.time.Duration
        [pc: 97, pc: 204] local: dur2 index: 9 type: java.time.Duration
        [pc: 121, pc: 204] local: d1 index: 10 type: double
        [pc: 145, pc: 204] local: d2 index: 12 type: double
      Stack map table: number of frames 6
        [pc: 18, full, stack: {}, locals: {java.lang.String[], int, int, int, java.time.Instant, int}]
        [pc: 28, same]
        [pc: 31, same]
        [pc: 55, full, stack: {}, locals: {java.lang.String[], int, int, int, java.time.Instant, java.time.Instant, java.time.Instant, int}]
        [pc: 65, same]
        [pc: 68, same]
}
 

Willibergi

Mitglied
Definitiv ist das kein gelungener Benchmarktest. Benutz doch Microbenchmark-Tools die dir das alles abnehmen

Aber was macht das für einen Unterschied? Im Prinzip ist die Vorgehensweise ja klar - ich gucke wie lange die eine Schleife braucht, dann wie lange die andere Schleife braucht und dann sehe ich welche effizienter ist.
Was machen Microbenchmark-Tools grundsätzlich anders?
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Zrebna Frage zu Test-Driven Development (TDD) Java Basics - Anfänger-Themen 3
W junit.Test not accessible? Java Basics - Anfänger-Themen 4
W Junit-Test (Java) Java Basics - Anfänger-Themen 4
W Testfälle bei Java ( Junit-Test) Java Basics - Anfänger-Themen 3
D Hilfe bei Calculator Test Java Basics - Anfänger-Themen 15
U jUnit 5 Test für eine addMethode Java Basics - Anfänger-Themen 18
M Test auf Exceptions schreiben Java Basics - Anfänger-Themen 11
P Eclipse Karate Framework API Test . Unexpected Error: the trustAnchors parameter must be non-empty Java Basics - Anfänger-Themen 1
I Variable innerhalb Methode: Local variable test defined in an enclosing scope must be final or effectively final Java Basics - Anfänger-Themen 3
A Junit Test für MysqlDataSource JDBC Java Basics - Anfänger-Themen 3
A Test Junit Java Basics - Anfänger-Themen 1
H Junit test Java Basics - Anfänger-Themen 12
P JUnitTest Best Practise (Ein Assert pro Test?) Java Basics - Anfänger-Themen 10
P Methoden JUnit 4 - Test Java Basics - Anfänger-Themen 6
Mr_Kleeblatt Operatoren if (arri[i] != "test.java"&& arri[i] != "test.class") Java Basics - Anfänger-Themen 3
N Fehler bei JUnit Test Java Basics - Anfänger-Themen 5
L Test-Methoden schreiben Java Basics - Anfänger-Themen 13
D Test auf Dopplungen Java Basics - Anfänger-Themen 32
neerual Klassen Wie rufe ich Klassen, die andere Klassen extenden in einer Test Unit auf? Java Basics - Anfänger-Themen 10
B JUnit Test erstellen Java Basics - Anfänger-Themen 6
B zzz.test Java Basics - Anfänger-Themen 13
W Problem bei JUnit Test Aufgabe Java Basics - Anfänger-Themen 15
W JUnit Test und HashCode Java Basics - Anfänger-Themen 14
C Erste Schritte Hexidezimal-Test Java Basics - Anfänger-Themen 2
A Kfz - Händler Klasse. JUnit-Test gibt noch Fehler an, aber finde Ursache nicht Java Basics - Anfänger-Themen 7
B Palindrom Test mit Junit Java Basics - Anfänger-Themen 23
T Minesweeper Test Java Basics - Anfänger-Themen 2
S Junit Test Java Basics - Anfänger-Themen 2
F Test Java Basics - Anfänger-Themen 12
shiroX Methoden JUnit-Test einer void-Methode Java Basics - Anfänger-Themen 4
U Best Practice Datenbereitstellung Unit Test Java Basics - Anfänger-Themen 6
B Binäre Suche - Junit Test Java Basics - Anfänger-Themen 6
B Datentypen Test float und double speichern Zahlen nur ungefähr Java Basics - Anfänger-Themen 4
Z Vererbung Test auf Normalverteilung, Wilcoxon Java Basics - Anfänger-Themen 3
M Assertion NotNull Test Java Basics - Anfänger-Themen 3
S Separate Funktion für JUnit-Test Java Basics - Anfänger-Themen 3
W Test, ob Datei existiert, schlägt fehl Java Basics - Anfänger-Themen 4
T JUnit test failed Java Basics - Anfänger-Themen 3
H Array Test Methode schreiben Java Basics - Anfänger-Themen 3
R JUnit Test mit einer Dateistruktur als Testparameter Java Basics - Anfänger-Themen 3
V Bruchrechner Test Java Basics - Anfänger-Themen 7
T Test läuft schief Java Basics - Anfänger-Themen 3
shiroX OOP Array kleinste Zahl mit jUnit test Java Basics - Anfänger-Themen 3
G mache aus Test nach sortieren estt oder java aajv Java Basics - Anfänger-Themen 5
S Code stimmt nicht für vorgegebenen JUnit-Test Java Basics - Anfänger-Themen 2
x22 Java Multiple Choice Test Java Basics - Anfänger-Themen 8
R JUnit Test mit mehrfach ausgeführt Java Basics - Anfänger-Themen 6
B JUnit - Mini-Test Java Basics - Anfänger-Themen 9
T Unterschied zwischen Integrationstest und JUnit test? Java Basics - Anfänger-Themen 12
N Test mit assert Java Basics - Anfänger-Themen 9
Y Junit Test - Testwert ändert sich Java Basics - Anfänger-Themen 12
K Palindrom Test Java Basics - Anfänger-Themen 9
S Performance-/Stress Test für Webanwendung Java Basics - Anfänger-Themen 2
V Mediaplayer - NullPointerException bei Unit-Test Java Basics - Anfänger-Themen 4
H Ich kann mein Java Programm Test.class nicht ausführen Java Basics - Anfänger-Themen 6
H Javabefehl Test Java Basics - Anfänger-Themen 3
S Hilfe zu Java-Programm und JUnit Test!! Java Basics - Anfänger-Themen 5
T JUNit Test IOException Java Basics - Anfänger-Themen 5
H lucas-test Java Basics - Anfänger-Themen 14
P White-Box-Test Verständnisproblem Java Basics - Anfänger-Themen 11
N Methoden Test ob Server vorhanden ist Java Basics - Anfänger-Themen 4
N Test Datei = Bild Java Basics - Anfänger-Themen 5
S Erste Schritte 1. Test Programm Java Basics - Anfänger-Themen 21
Spin JUNIT Test Case - Problem bei testen Java Basics - Anfänger-Themen 2
T brauche HILFE beim Junit test:eek: Java Basics - Anfänger-Themen 11
timbeau JUnit Test Dauer speichern/loggen Java Basics - Anfänger-Themen 16
E Am Mittwoch Test und ich checks überhaupt nich Java Basics - Anfänger-Themen 27
A junit test wann verwendet man "was"? Java Basics - Anfänger-Themen 4
J JUnit Test Java Basics - Anfänger-Themen 2
D Test einer Chipkarte Java Basics - Anfänger-Themen 2
J Problem mit Test-Klasse Java Basics - Anfänger-Themen 4
E Test, ob String in Double umwandelbar ist Java Basics - Anfänger-Themen 3
J Test steht vor der Tür !! Java Basics - Anfänger-Themen 2
X Array nur mit Zahlen (test) Java Basics - Anfänger-Themen 11
Houly JUnit Test Suite anlegen Java Basics - Anfänger-Themen 6
F Primitiver Lucas-Lehmer-Test hängt sich auf Java Basics - Anfänger-Themen 7
M Erster HashMap-test Java Basics - Anfänger-Themen 5
O Test auf JComponent Java Basics - Anfänger-Themen 7
pun Junit Test erkennt Exception nicht.. Java Basics - Anfänger-Themen 14
D C0 und C1 Test nochmal Java Basics - Anfänger-Themen 9
D C0 und C1 Test Java Basics - Anfänger-Themen 3
G BlueJ jUnit Test Java Basics - Anfänger-Themen 6
J Test auf UTF-8 Java Basics - Anfänger-Themen 2
M Wo und wie speich. ich .java und wo den zugehörigen test? Java Basics - Anfänger-Themen 2
Shalimar Test, ob mehr pos. oder neg. Zahlen Java Basics - Anfänger-Themen 3
M test Java Basics - Anfänger-Themen 5
M test Java Basics - Anfänger-Themen 2
M test Java Basics - Anfänger-Themen 10
V Test mit JUnit verbinden Java Basics - Anfänger-Themen 3
M test Java Basics - Anfänger-Themen 4
H Miller Rabin Test Primzahlen werden teilweise nicht gefunden Java Basics - Anfänger-Themen 5
C Multiple Choice Test Java Java Basics - Anfänger-Themen 5
G Grundfläche färben, ein Bild (NORTH) ind Test darunter? Java Basics - Anfänger-Themen 6
M Palindrom Test mit Char-arrays! Java Basics - Anfänger-Themen 3
M Java Test Übungsfragen Hilfe! Java Basics - Anfänger-Themen 5
B JUnit Test Klasse Rational Java Basics - Anfänger-Themen 12
N class Test<E extends MyAbstractClass> => typ von E? Java Basics - Anfänger-Themen 5
G jar cvf test.war -C src/ WEB-INF -C src/ ALLE JSP Wildcard? Java Basics - Anfänger-Themen 2
0 Quadratzahl-Test Java Basics - Anfänger-Themen 4
C Unsupported major.minor bei jUnit Test Java Basics - Anfänger-Themen 2

Ähnliche Java Themen

Neue Themen


Oben