Geschwindigkeitsabhängigkeit von Anz. d. Operatoren pro Zeile

Blackhole16

Bekanntes Mitglied
Liebes java-Forum,

Mir ist heute aufgefallen, dass die Geschwindigkeit u.a. davon abhängig ist, wie viele Operatoren in einer Zeile stehen, oder ob man diese teilt. Zum Veranschaulichen dieses Beispiel:

Java:
void slow() {
		long time = System.nanoTime();
		double a = Math.sqrt(5 + 7*9/2 - 3*5%7);
		time = System.nanoTime() - time;
		System.out.println(a);
		System.out.println(time);
	}
	
	void fast() {
		long time = System.nanoTime();
		double a = 5;
		a += 7*9/2;
		a -= 3*5%7;
		a = Math.sqrt(a);
		time = System.nanoTime() - time;
		System.out.println(a);
		System.out.println(time);
	}

Wieso ist fast() (283 ns) schneller als slow() (um 15.000 ns), obwohl beides an sich die selben Operatoren hat? Und warum ist dies ohne Math.sqrt(), also generell, wenn man keine Funktionen nimmt, gleich schnell?

mfg
BH16
 
G

Gast2

Gast
Erstmal vorne weg: Solche Microbenchmarks sind immer kritisch zu betrachten, die sagen meist nur wenig aus!

Als Beispiel:
Ich nehme an du prüfst das folgendermaßen:
Java:
public static void main(String[] args) throws Exception {
	slow ();
	fast ();
}
und bekommst als Ausgabe sowas wie:
Code:
5.916079783099616
24948
5.916079783099616
279

Dann dreh das ganze mal um ;)
Java:
public static void main(String[] args) throws Exception {
	fast ();
	slow ();
}
Ausgabe:
Code:
5.916079783099616
26543
5.916079783099616
271
Plötzlich ist fast() gar nicht mehr so schnell ;) Das spielt dir wohl der JIT mit rein.
 

Bernd Hohmann

Top Contributor
Vorallem weil bei "slow()" der gesamte Ausdruck zu 35.0d zusammengefasst wird wärend bei "fast()" tatsächlich erst addiert/subtrahiert wird.

Bei 10.000 Durchläufen sieht die Welt schon anders aus :)

Bernd
 

Phash

Top Contributor
mach einfach mal VIELE durchlaeufe und zwar mehrmals
und beide Versionen getrennt voneinander.

Wie Eike schon sagte, wirds anders aussehen, wenn du andersrum aufrufst.

bei mir sind die Funktionen ca. 10% auseinander - zugunsten der schnelleren slow() methode :)
 
Zuletzt bearbeitet:

Blackhole16

Bekanntes Mitglied
ich habs mal geändert:

Java:
public static void main(String[] args) {
		long time = 0;
		for (int i = 0; i < 10000; i++) {
			long  akttime = System.nanoTime();
			fast();
			akttime = System.nanoTime() - akttime;
			time += akttime;
		}
		System.out.println(time);
	}
	
	static void slow() {
		double a = Math.sqrt(5 + 7*9/2 - 3*5%7);
	}
	
	static void fast() {
		double a = 5;
		a += 7*9/2;
		a -= 3*5%7;
		a = Math.sqrt(a);
	}

wenn ich fast teste, dann dauert es um die 110.000ns und wenn ich slow teste, dauert es um die 100.000. Das wundert mich extrem, das Beispiel scheint schlecht zu sein :bloed:

Eigentlich habe ich es beim Heron-Verfahren mit BigDecimals gemerkt, allerdings hat das bei meinen Tests eben exakt die Selbe Geschwindigkeit gehabt o_O

Auf jeden Fall hatte ich heute das Problem, dass ich eine Funktion in Mathe für meinen CAS TI Voyage 200 geschrieben habe, die mir die Ableitung jeder Funktion bestimmt (Thema gerade begonnen, zu faul zum rechnen :p ). Bei hohen Exponenten hat der TR gezeigt, dass er zwar noch rechnet, allerdings habe ich nach 15min abgebrochen.
Als ich dann alles in eine eigene Zeile geschrieben habe, hat es bei der selben Funktion geklappt, nur noch ca. 3 sec hats gebraucht.

Aber dass das in Java jetzt doch keinen unterschied mehr macht, obwohl ich vorher starke Differenzen mal bemerkt habe, wundert mich.

Habt ihr noch Ideen, wie man dies testen könnte/beweisen kann, dass kein Unterschied da ist?

mfg
BH16

PS: Iwie bin ich jetzt echt verwirrt ???:L
 

Marco13

Top Contributor
Mit
javap -c TheClass.class
kann man sich den Bytecode ansehen, der generiert wird. Was der JIT draus macht ist nochmal eine andere Frage, aber eine Form einer "Ground Truth" hat man dann schonmal....
 

Bernd Hohmann

Top Contributor
wenn ich fast teste, dann dauert es um die 110.000ns und wenn ich slow teste, dauert es um die 100.000. Das wundert mich extrem, das Beispiel scheint schlecht zu sein :bloed:

Ja: die meisste Zeit verbringt er in
Code:
System.nanoTime();
. Da die Zahlen alle Konstant sind kann es passieren dass Dir die ganze Mathematik vom JIT wegoptimiert wird.

Bernd
 

Marco13

Top Contributor
Da die Zahlen alle Konstant sind kann es passieren dass Dir die ganze Mathematik vom JIT wegoptimiert wird.

Und insbesondere auch die Funktionsaufrufe an sich: Das Ergebnis wird nicht verwendet.

Insgesamt sind solche Microbenchmarks schwierig, speziell wenn es um sowas "kleines" wie ein paar alberne Instruktionen geht (bei denen wenn überhaupt nur sqrt wenigstens etwas Zeit braucht).

Man kann sich ein bißchen mehr bemühen
Java:
public class BogusSpeedTest
{
    public static void main(String[] args) 
    {
        long before = 0;
        long after = 0;

        for (int r=1000000; r<=10000000; r+=1000000)
        {
            before = System.nanoTime();
            double sumF = 0;
            for (int i = 0; i < r; i++) 
            {
                sumF += fast();
            }
            after = System.nanoTime();
            System.out.println("With "+r+" runs fast "+sumF+" duration "+(after-before)/1e6+" ms");

            before = System.nanoTime();
            double sumS = 0;
            for (int i = 0; i < r; i++) 
            {
                sumS += slow();
            }
            after = System.nanoTime();
            System.out.println("With "+r+" runs slow "+sumS+" duration "+(after-before)/1e6+" ms");
            
        }
    }
    
    static double slow() 
    {
        return Math.sqrt(5 + 7*9/2 - 3*5%7);
    }
    
    static double fast() {
        double a = 5;
        a += 7*9/2;
        a -= 3*5%7;
        return Math.sqrt(a);
    }
}
Aber wie zu erwarten sind die Zeiten praktisch gleich.

Etwas überraschend könnte der Bytecode sein:
Code:
static double slow();
  Code:
   0:   ldc2_w  #84; //double 35.0d
   3:   invokestatic    #86; //Method java/lang/Math.sqrt:(D)D
   6:   dreturn

static double fast();
  Code:
   0:   ldc2_w  #92; //double 5.0d
   3:   dstore_0
   4:   dload_0
   5:   ldc2_w  #94; //double 31.0d
   8:   dadd
   9:   dstore_0
   10:  dload_0
   11:  dconst_1
   12:  dsub
   13:  dstore_0
   14:  dload_0
   15:  invokestatic    #86; //Method java/lang/Math.sqrt:(D)D
   18:  dreturn
Das zweite sieht schon aufwändiger auf, wegen der ganzen stores, aber wenn der JIT einmal drübergelaufen ist, stellt sich die Frage nicht mehr: Spätestens dann dürfte das zu einem einzelnen return-statement verkommen, das ggf. auch gleich noch geinlinet wird (und wenn man die main ein paar tausend mal aufrufen würde, könnte er ggf. noch sämtliche Schleifen wegoptimieren und direkt sum=X.XXX setzen...)
 

Bernd Hohmann

Top Contributor
Und insbesondere auch die Funktionsaufrufe an sich: Das Ergebnis wird nicht verwendet.

Ja - es hat mich auch gewundert, dass Javac das nicht erkennt und einfach wegschmeisst.

Auf der einen Seite seltsam, auf der anderen Seite finde ich es gut dass der Compiler nur sowas Grundlegendes wie "1+2*3+4" optimiert und den Rest JIT überlässt weil ich die blutige Erfahrung machen durfte dass optimierende Compilerstrategien auch suboptimale Seiteneffekte haben.

Das zweite sieht schon aufwändiger auf, wegen der ganzen stores, aber wenn der JIT einmal drübergelaufen ist, stellt sich die Frage nicht mehr: Spätestens dann dürfte das zu einem einzelnen return-statement verkommen, das ggf. auch gleich noch geinlinet wird (und wenn man die main ein paar tausend mal aufrufen würde, könnte er ggf. noch sämtliche Schleifen wegoptimieren und direkt sum=X.XXX setzen...)

Ark hatte neulich auf meine Anfrage hin eine Info gepostet, wie man an den erzeugten Maschinencode des JIT rankommt - finde es aber gerade nicht und hab auch verpennt das irgendwo zu speichern.

Bernd
 

Marco13

Top Contributor
Ja, -XX:+PrintOptoAssembly - das schwierige ist, dass man dafür eine Debug-JVM braucht, die hat man üblicherweise nicht grundlos auf der Platte rumfliegen.
 

Ark

Top Contributor
Ja - es hat mich auch gewundert, dass Javac das nicht erkennt und einfach wegschmeisst.
Dafür gibt's mehrere Gründe, der einfachste: Die aufgerufene Methode könnte eine (Runtime)Exception werfen, was beim statischen Wegoptimieren zu einer Änderung der Semantik führen würde.

Ark hatte neulich auf meine Anfrage hin eine Info gepostet, wie man an den erzeugten Maschinencode des JIT rankommt - finde es aber gerade nicht und hab auch verpennt das irgendwo zu speichern.
https://wikis.oracle.com/display/HotSpotInternals/PrintAssembly

Ark
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
B Spielereien mit bit wise Operatoren und langen Binärzahlen Java Basics - Anfänger-Themen 3
K Für was braucht man die left und right shift operatoren? Was bringen die, also welchen Zweck haben die? Java Basics - Anfänger-Themen 15
Kleinerals2 NaN Operatoren Java Basics - Anfänger-Themen 3
S Und-Abfrage mit mehreren Ungleich-Operatoren Java Basics - Anfänger-Themen 17
P Datentypen, Klassen, Operatoren, Wrapperklassen Java Basics - Anfänger-Themen 2
D Erste Schritte Operatoren zur Manipulation von Bits "~" Java Basics - Anfänger-Themen 5
M Operatoren Umwandlung div. Operatoren Java Basics - Anfänger-Themen 7
V Operatoren Was will mir die Tabelle in meinem Lehrbuch sagen? (logische Operatoren) Java Basics - Anfänger-Themen 4
S Bitweise Operatoren" >>>",">>","<<" erklärung Java Basics - Anfänger-Themen 5
G operatoren Java Basics - Anfänger-Themen 3
beatles Operatoren Operatoren - Berechnung Java Basics - Anfänger-Themen 40
T Verständnisfrage Zuweisungs-/arithmet. Operatoren Java Basics - Anfänger-Themen 2
X Shift-Operatoren Java Basics - Anfänger-Themen 1
P Bitweise Operatoren Java Basics - Anfänger-Themen 2
Phillip Bitweise Operatoren Java Basics - Anfänger-Themen 11
C Operatoren Java Basics - Anfänger-Themen 6
P Taschenrechner, operatoren Java Basics - Anfänger-Themen 4
M Einfache und Doppelte Operatoren Java Basics - Anfänger-Themen 3
S Operatoren & Terminierung Java Basics - Anfänger-Themen 1
A Bitweise Operatoren Java Basics - Anfänger-Themen 1
O Priorität bei Operatoren Java Basics - Anfänger-Themen 4
N Potenzierung durch einfache Operatoren Java Basics - Anfänger-Themen 13
M hexadezimal in binär mit Hilfe von Shift-Operatoren Java Basics - Anfänger-Themen 6
S Arithmetische Operatoren Java Basics - Anfänger-Themen 7
L Erste Schritte Fragen zu Arrays, Inkrement Operatoren, Dekrement Operatoren ? Java Basics - Anfänger-Themen 9
lulas[]args Fehler - Logische Operatoren Java Basics - Anfänger-Themen 9
H Nur Zahlen, Klammern und Operatoren Java Basics - Anfänger-Themen 3
D Frage zu Bit Operatoren in der Programmierung Java Basics - Anfänger-Themen 9
P Anzahl der else if Operatoren begrenzt?? Java Basics - Anfänger-Themen 7
L [Logische Operatoren] referenzierbar? Java Basics - Anfänger-Themen 3
W Was tun die Operatoren ? und : (Bedingungen) Java Basics - Anfänger-Themen 15
W Datentypen Operatoren für eigenen Datentyp nutzen Java Basics - Anfänger-Themen 2
G Logische und Bitweise Operatoren Java Basics - Anfänger-Themen 2
S Datentypen Operatoren und Ausdrücke (formel richtig rechnen) Java Basics - Anfänger-Themen 8
E Logische Operatoren && und & Java Basics - Anfänger-Themen 14
? Operatoren && || Java Basics - Anfänger-Themen 10
M Aufgabe Arithmetische Operatoren Java Basics - Anfänger-Themen 12
H While Schleife mit Operatoren Java Basics - Anfänger-Themen 14
T Rechnen mit Operatoren Java Basics - Anfänger-Themen 2
M Arithmetische Operatoren Java Basics - Anfänger-Themen 40
V Sonderzeichen als eigene "Operatoren" im JTextField Java Basics - Anfänger-Themen 4
M Sind ternäre Operatoren für einen guten Programmierstil wichtig ? Java Basics - Anfänger-Themen 10
E IF Anweisung mit logischen Operatoren Java Basics - Anfänger-Themen 18
JStickman Was bringen Bit-Operatoren? Java Basics - Anfänger-Themen 14
J Matheaufgabe aus String mit mehreren Operatoren Java Basics - Anfänger-Themen 16
D Logische Operatoren Java Basics - Anfänger-Themen 6
D Grundlagen - Operatoren Java Basics - Anfänger-Themen 5
1 Datentypen Rückgabetyp von Java-Operatoren Java Basics - Anfänger-Themen 2
V Bitweise Operatoren in der Grafikprogrammierung Java Basics - Anfänger-Themen 2
SebSnake Operatoren für eigene Datentypen Java Basics - Anfänger-Themen 3
M logische operatoren Java Basics - Anfänger-Themen 2
C Variablen für Operatoren Java Basics - Anfänger-Themen 3
W Rangfolge von Operatoren Java Basics - Anfänger-Themen 16
N zahlen und operatoren gemischt in einem Feld Java Basics - Anfänger-Themen 9
T Logische Operatoren Java Basics - Anfänger-Themen 39
C Dynamische Operatoren! Java Basics - Anfänger-Themen 5
G Shift Operatoren Java Basics - Anfänger-Themen 4
R Bedingte Opeatoren / Verschachtelte Operatoren Java Basics - Anfänger-Themen 4
7 Operatoren in der While Schleife Java Basics - Anfänger-Themen 5
H Postfix Operatoren Java Basics - Anfänger-Themen 2
S Variablen + Operatoren "mixen" Java Basics - Anfänger-Themen 5
F Experimente mit Bit-Operatoren Java Basics - Anfänger-Themen 7
G Nutzen von bitweisen Operatoren Java Basics - Anfänger-Themen 8
J Operatoren in Java Java Basics - Anfänger-Themen 2
S Verwendung bitweiser Operatoren Java Basics - Anfänger-Themen 6
R Binäre logische Operatoren Java Basics - Anfänger-Themen 21
Glühlampe Usereingabe in der gleichen Zeile ausgeben Java Basics - Anfänger-Themen 6
Ü Zweidimensionales Array in der ersten Zeile deklarieren Java Basics - Anfänger-Themen 13
padde479 Zeile entfernen TableModel Java Basics - Anfänger-Themen 11
F Arraylist<String>Ein Wort pro Zeile Java Basics - Anfänger-Themen 6
G Compiler-Fehler Fehler in Zeile 1 beheben, wie? Java Basics - Anfänger-Themen 9
I Wortkette in umgekehrter Rheinfolge + in neuer Zeile ausgeben Java Basics - Anfänger-Themen 4
W String einer Textdatei in einzelne Stringobjekte pro Zeile aufteilen Java Basics - Anfänger-Themen 14
M Spezifischen Wert einer Zeile aus .txt Datei entnehmen Java Basics - Anfänger-Themen 15
AkiJou Zeile in 2d Array löschen Java Basics - Anfänger-Themen 2
LilliCherry Array in einer Zeile ausgeben Java Basics - Anfänger-Themen 6
S Variablen Letzte Zeile eines Strings entfernen Java Basics - Anfänger-Themen 1
LFB In einer For-Schleife alles in einer Zeile ausgeben Java Basics - Anfänger-Themen 14
javapingu Jeglichen Inhalt einer Textdatei nach Zeile n löschen Java Basics - Anfänger-Themen 8
S Zufällige ungerade Zeile aus Text-Datei lesen Java Basics - Anfänger-Themen 5
G JTable, Zeile auswählen und Ergebnis an Schaltfläche übergeben Java Basics - Anfänger-Themen 4
Zwanglos Warum wird nur die erste Zeile im while Block ausgeführt? Java Basics - Anfänger-Themen 8
dieter000 Wie schreibe ich diese ZEile um? Java Basics - Anfänger-Themen 1
crrnogorka Letzte Zeile einer Tabelle "überschreibt" alle anderen Zeilen Java Basics - Anfänger-Themen 1
M In gleicher zeile hinter ausgabe noch etwas ausgeben Java Basics - Anfänger-Themen 1
P Welche Zeile in Tadople gibt einen compiler error? Java Basics - Anfänger-Themen 5
I ArrayList erstellen innerhalb einer Zeile? Java Basics - Anfänger-Themen 3
S Datenbank Tabelle eine Zeile an einer bestimmten Stelle einfügen Java Basics - Anfänger-Themen 2
S Gesamten String in einer Zeile ausgeben Java Basics - Anfänger-Themen 2
J ObjectOutputStream writeChars, komische Zeichen nur in 1. Zeile Java Basics - Anfänger-Themen 2
T Was macht diese Zeile? Java Basics - Anfänger-Themen 9
A Jede x-te Zeile, lösche 10 Zeilen Java Basics - Anfänger-Themen 9
L Tiefe Kopie einer Zeile eines zweidimensionalen Arrays Java Basics - Anfänger-Themen 1
B Code Zeile unklar Java Basics - Anfänger-Themen 9
ruutaiokwu Ausgegebene Zeile ersetzen mit neuem Text Java Basics - Anfänger-Themen 3
F Zeile in Ordner Java Basics - Anfänger-Themen 4
jaleda100 JTextArea Zeile einfügen Java Basics - Anfänger-Themen 1
M BufferedReader neue Zeile nach Knopfdruck Java Basics - Anfänger-Themen 9
F Mehrere Zeilen zu einer Zeile zusammenfügen und in eine Datei schreiben Java Basics - Anfänger-Themen 1
MaximilianTM Input/Output Einlesen und bearbeiten einer text Datei / Zeile Java Basics - Anfänger-Themen 5

Ähnliche Java Themen

Neue Themen


Oben