gpt4 book ai didi

recursion - 带尾递归的慢字节码

转载 作者:行者123 更新时间:2023-12-04 19:58:03 25 4
gpt4 key购买 nike

灵感来自 this SO question 的回答我使用代码来检查针对尾递归的命令式循环:

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 ());

对于字节码和 native 代码,结果是
str@s131-intel:~> ./bench_loop
recursive function: 20.7656 s
while loop with ref counter buitin incr: 12.0642 s
str@s131-intel:~> ./bench_loop.opt
recursive function: 0.755594 s
while loop with ref counter buitin incr: 0.753947 s

问题是:20 到 12 秒的执行时间相差很大的原因是什么?

编辑,我的结论:

一个函数调用 apply (在字节码中)涉及堆栈大小检查、可能的堆栈扩大和信号检查。为了获得最佳性能, native 代码编译器将提供。

(旁注:在这里询问 SO 因为它对搜索引擎友好。)

最佳答案

查看 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)))

显然 assignapply 快.在函数调用时似乎会检查堆栈溢出和信号,但不会检查简单的分配。详情请看: https://github.com/ocaml/ocaml/blob/trunk/byterun/interp.c

关于recursion - 带尾递归的慢字节码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31381742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com