inspired answer this question took code check imperative loop against tail recursion:
let rec nothingfunc = match | 1000000000 -> 1 | _ -> nothingfunc (i+1) let nothingloop1 () = let = ref 0 in while !i < 1000000000 incr 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 ref counter buitin incr: %g s\n%!" (timeit nothingloop1 ()); for bytecode , native code results are
str@s131-intel:~> ./bench_loop recursive function: 20.7656 s while loop ref counter buitin incr: 12.0642 s str@s131-intel:~> ./bench_loop.opt recursive function: 0.755594 s while loop ref counter buitin incr: 0.753947 s the question is: reason big difference 20 12 seconds execution time?
edit, conclusion:
a function call apply (in byte code) involves stack size check, possible stack enlargement, , check signals. maximum performance native code compiler deliver.
(side note: asking here on because search engine friendly.)
look @ output of ocamlfind ocamlc -package unix test.ml -dlambda
(nothingloop1/1010 = (function param/1022 (let (i/1011 =v 0) (seq (while (< i/1011 100000000) (assign i/1011 (1+ i/1011))) 1))) (nothingfunc/1008 (function i/1009 (if (!= i/1009 100000000) (apply nothingfunc/1008 (+ i/1009 1)) 1))) so apparently assign faster apply. there seems checks stack overflows , signals @ function invocations, not simple assign. details, have at: https://github.com/ocaml/ocaml/blob/trunk/byterun/interp.c
Comments
Post a Comment