durch die Antwort inspiriert zu this SO question nahm ich den Code ein Imperativ Schleife gegen Endrekursion zu überprüfen:langsamen Bytecode mit Endrekursion
let rec nothingfunc i =
match i with
| 1000000000 -> 1
| _ -> nothingfunc (i+1)
let nothingloop1() =
let i = ref 0 in
while !i < 1000000000 do incr i done;
1
let timeit f v =
let t1 = Unix.gettimeofday() in
let _ = f v in
let t2 = Unix.gettimeofday() in
t2 -. t1
let() =
Printf.printf "recursive function: %g s\n%!" (timeit nothingfunc 0);
Printf.printf "while loop with ref counter buitin incr: %g s\n%!" (timeit nothingloop1());
Für Bytecode und nativen Code die Ergebnisse sind
[email protected]:~> ./bench_loop
recursive function: 20.7656 s
while loop with ref counter buitin incr: 12.0642 s
[email protected]:~> ./bench_loop.opt
recursive function: 0.755594 s
while loop with ref counter buitin incr: 0.753947 s
Die Frage ist: Was ist der Grund für die große Differenz 20 bis 12 Sekunden Ausführungszeit?
bearbeiten, mein Fazit:
Ein Funktionsaufruf apply
(in Byte-Code), um eine Stapelgröße zu überprüfen, mögliche Stapel Erweiterung beinhaltet, und einen Scheck für Signale. Für maximale Leistung liefert der native Code Compiler.
(Randbemerkung:. Fragen hier auf SO, weil sie suchmaschinenfreundlich ist)
opt in ocamlopt steht für optimiert. Der Bytecode-Compiler führt weniger Optimierungen durch, da er nie seinen Zweck erfüllt. Obwohl viele Optimierungen noch gemacht werden. Und zum Beispiel bei der aktuellen Version des Compilers (4.03) beträgt der Unterschied etwa 10% (9,3 gegenüber 8,3 Sekunden). – ivg