Hi
Eigentlich dachte ich ja, dass ich mir für die meisten Gründe scheinbar unerklärlichen Verhaltens zumindest irgendwas mit JIT, caching & Co zusammenreimen könnte, aber das hier kann ich mir im Moment nicht erklären - und es scheint etwas so ... "elementares" zu sein, dass mich das jetzt schon ein bißchen wurmt :autsch: :
Das Rechnen mit kleinen Zahlen scheint deutlich (!) langsamer zu sein, als das Rechnen mit "normalen" Zahlen. Gemerkt habe ich das eben in einem größeren Programm eher zufällig, konnte es aber nicht recht glauben, und habe deswegen nochmal einen Microbenchmark gemacht (und natürlich auf die übliche Weise versucht, diesem so viel Aussagekraft wie möglich zu geben: Mehrere Durchläufe mir größer werdenen Eingaben und abwechselndem Aufruf der beiden Fälle).
Das ganze getestet mit Java6/29 (-server) auf Win7/64, Core i7@3Ghz... das Ergebnis:
Ja, gut, man könnte da jetzt zwar auch spekulieren, dass die Normalisierung für die Mutliplikation tief im Prozessor seine Zeit braucht oder was weiß ich, und ein kleiner Unterschied wäre ja OK, aber es kann doch nicht sein, dass das Multiplizieren von ein paar "kleinen" Zahlen durchgängig hundert mal so lange dauert wie das von ein paar "normalen" Zahlen!? :autsch: Soll man in solchen Fällen wirklich alle Zahlen von Hand "normalisieren", damit der arme Herr Prozessor das nicht machen muss? :noe:
Oder ist einfach nur mein Computer kaputt? ;(
Eigentlich dachte ich ja, dass ich mir für die meisten Gründe scheinbar unerklärlichen Verhaltens zumindest irgendwas mit JIT, caching & Co zusammenreimen könnte, aber das hier kann ich mir im Moment nicht erklären - und es scheint etwas so ... "elementares" zu sein, dass mich das jetzt schon ein bißchen wurmt :autsch: :
Das Rechnen mit kleinen Zahlen scheint deutlich (!) langsamer zu sein, als das Rechnen mit "normalen" Zahlen. Gemerkt habe ich das eben in einem größeren Programm eher zufällig, konnte es aber nicht recht glauben, und habe deswegen nochmal einen Microbenchmark gemacht (und natürlich auf die übliche Weise versucht, diesem so viel Aussagekraft wie möglich zu geben: Mehrere Durchläufe mir größer werdenen Eingaben und abwechselndem Aufruf der beiden Fälle).
Java:
import java.util.*;
class SmallNumbers
{
public static void main(String args[])
{
for (int n=1000; n<=10000000; n*=10)
{
float a[] = new float[n];
float b[] = new float[n];
float dot = 0;
long before = 0;
long after = 0;
int runs = 5;
fill(a, 1e-20f);
fill(b, 1e-20f);
before = System.nanoTime();
dot = 0;
for (int i=0; i<runs; i++)
{
dot += dot(a,b);
}
after = System.nanoTime();
System.out.println("Small for "+n+" time "+(after-before)/1e6+" ms result "+dot);
fill(a, 1);
fill(b, 1);
before = System.nanoTime();
dot = 0;
for (int i=0; i<runs; i++)
{
dot += dot(a,b);
}
after = System.nanoTime();
System.out.println("Normal for "+n+" time "+(after-before)/1e6+" ms result "+dot);
}
}
private static void fill(float a[], float factor)
{
Random r = new Random(0);
for (int i=0; i<a.length; i++)
{
a[i] = r.nextFloat() * factor;
}
}
private static float dot(float a[], float b[])
{
float sum = 0;
for (int i=0; i<a.length; i++)
{
sum += a[i] * b[i];
}
return sum;
}
}
Das ganze getestet mit Java6/29 (-server) auf Win7/64, Core i7@3Ghz... das Ergebnis:
Code:
Small for 1000 time 0.619448 ms result 1.605676E-37
Normal for 1000 time 0.140942 ms result 1605.6758
Small for 10000 time 6.114442 ms result 1.6553897E-36
Normal for 10000 time 0.049765 ms result 16553.873
Small for 100000 time 53.807083 ms result 1.6730621E-35
Normal for 100000 time 0.511914 ms result 167305.3
Small for 1000000 time 531.612915 ms result 1.6681287E-34
Normal for 1000000 time 4.534153 ms result 1668135.5
Small for 10000000 time 5312.714176 ms result 1.6468518E-33
Normal for 10000000 time 54.758528 ms result 1.650076E7
Ja, gut, man könnte da jetzt zwar auch spekulieren, dass die Normalisierung für die Mutliplikation tief im Prozessor seine Zeit braucht oder was weiß ich, und ein kleiner Unterschied wäre ja OK, aber es kann doch nicht sein, dass das Multiplizieren von ein paar "kleinen" Zahlen durchgängig hundert mal so lange dauert wie das von ein paar "normalen" Zahlen!? :autsch: Soll man in solchen Fällen wirklich alle Zahlen von Hand "normalisieren", damit der arme Herr Prozessor das nicht machen muss? :noe:
Oder ist einfach nur mein Computer kaputt? ;(