Ich mochte zwei Dinge über Ihren Testfall nicht. Zuerst haben Sie alle Tests innerhalb desselben Prozesses ausgeführt. Im Umgang mit "groß" (mehrdeutig, ich weiß), aber wenn Sie sich mit etwas beschäftigen, wo Ihr Prozess mit der Erinnerung interagiert, ist Ihre Hauptsorge, sollten Sie immer Benchmark in einem separaten Lauf. Allein die Tatsache, dass wir den Müll gesammelt haben, kann die Ergebnisse früherer Läufe beeinflussen. Die Art und Weise, wie Sie Ihre Ergebnisse einkalkuliert haben, verwirrte mich irgendwie. Was ich getan habe, war, dass ich jeden einzelnen Run genommen habe und eine Null von der Anzahl der Male, die ich es gefahren bin. Ich lasse es auch für eine Reihe von "Wiederholungen" laufen, wobei jede Wiederholung zeitlich abgestimmt wird. Dann ausgedruckt die Anzahl der Millisekunden, die jeder Lauf dauerte.Hier ist mein Code:
import java.util.Random;
public class blah {
public static void main(String[] args){
stringComp();
}
private static void stringComp() {
int SIZE = 1000000;
int NUM_REPS = 5;
for(int j = 0; j < NUM_REPS; j++) {
Random r = new Random();
float f;
long start = System.currentTimeMillis();
for (int i=0;i<SIZE;i++){
f = r.nextFloat();
stringSpeed3(f,f,f,f,f,f);
}
System.out.print((System.currentTimeMillis() - start));
System.out.print(", ");
}
}
public static String stringSpeed1(float a, float b, float c, float x, float y, float z){
StringBuilder sb = new StringBuilder(72).append("[").append(a).append(",").append(b).append(",").append(c).append("][").
append(x).append(",").append(y).append(",").append(z).append("]");
return sb.toString();
}
public static String stringSpeed2(float a, float b, float c, float x, float y, float z){
StringBuilder sb = new StringBuilder().append("[").append(a).append(",").append(b).append(",").append(c).append("][").
append(x).append(",").append(y).append(",").append(z).append("]");
return sb.toString();
}
public static String stringSpeed3(float a, float b, float c, float x, float y, float z){
return "["+a+","+b+","+c+"]["+x+","+y+","+z+"]";
}
public static String stringSpeed4(float a, float b, float c, float x, float y, float z){
return String.format("[%f,%f,%f][%f,%f,%f]", a,b,c,x,y,z);
}
}
Jetzt meine Ergebnisse:
stringSpeed1(SIZE = 10000000): 11548, 11305, 11362, 11275, 11279
stringSpeed2(SIZE = 10000000): 12386, 12217, 12242, 12237, 12156
stringSpeed3(SIZE = 10000000): 12313, 12016, 12073, 12127, 12038
stringSpeed1(SIZE = 1000000): 1292, 1164, 1170, 1168, 1172
stringSpeed2(SIZE = 1000000): 1364, 1228, 1230, 1224, 1223
stringSpeed3(SIZE = 1000000): 1370, 1229, 1227, 1229, 1230
stringSpeed1(SIZE = 100000): 246, 115, 115, 116, 113
stringSpeed2(SIZE = 100000): 255, 122, 123, 123, 121
stringSpeed3(SIZE = 100000): 257, 123, 129, 124, 125
stringSpeed1(SIZE = 10000): 113, 25, 14, 13, 13
stringSpeed2(SIZE = 10000): 118, 23, 24, 16, 14
stringSpeed3(SIZE = 10000): 120, 24, 16, 17, 14
//This run SIZE is very interesting.
stringSpeed1(SIZE = 1000): 55, 22, 8, 6, 4
stringSpeed2(SIZE = 1000): 54, 23, 7, 4, 3
stringSpeed3(SIZE = 1000): 58, 23, 7, 4, 4
stringSpeed1(SIZE = 100): 6, 6, 6, 6, 6
stringSpeed2(SIZE = 100): 6, 6, 5, 6, 6
stirngSpeed3(SIZE = 100): 8, 6, 7, 6, 6
Wie Sie aus meinen Ergebnissen, auf Werte sehen, die in den „mittleren Bereich“ jedes Mal in Folge rep schneller bekommt sind. Dies wird, glaube ich, dadurch erklärt, dass die JVM rennt und sich den Speicher aneignet, den sie benötigt. Wenn die "Größe" ansteigt, darf dieser Effekt nicht mehr übernommen werden, da zu viel Speicher für den Garbage Collector vorhanden ist und der Prozess sich wieder einklinken kann. Wenn Sie einen "repetitiven" Benchmark wie diesen verwenden, bei dem der Großteil Ihres Prozesses in niedrigeren Cache-Ebenen statt im RAM-Speicher vorhanden sein kann, ist Ihr Prozess für Branch-Prädiktoren noch empfindlicher. Diese sind sehr schlau und würden herausfinden, was Ihr Prozess macht, und ich kann mir vorstellen, dass die JVM dies verstärkt. Dies hilft auch zu erklären, warum die Werte in anfänglichen Schleifen langsamer sind und warum die Art, wie Sie sich dem Benchmarking nähern, eine schlechte Lösung ist. Deshalb denke ich, dass Ihre Ergebnisse für Werte, die nicht "groß" sind, verzerrt sind und seltsam erscheinen. Wenn der "memory footprint" Ihres Benchmarks erhöht wird, wirkt sich diese Verzweigungsvorhersage weniger (prozentual) aus als die großen Strings, die Sie angehängt haben, im RAM verschoben werden.
Vereinfachte Schlussfolgerung: Ihre Ergebnisse für "große" Läufe sind einigermaßen gültig und scheinen mir ähnlich zu sein (obwohl ich immer noch nicht vollständig verstehe, wie Sie Ihre Ergebnisse erhalten haben, aber die Prozentsätze scheinen im Vergleich gut zu sein). Ihre Ergebnisse für kleinere Läufe sind jedoch aufgrund der Art Ihres Tests nicht gültig.
Das Verhalten der Algorithmen zwischen 100 und .... ??? – ChrisCM
behoben, es aus irgendeinem Grund abgeschnitten – greedybuddha
Große Frage, mit Forschung und Daten, um es zu sichern. +1 – syb0rg