Clojure REPL为这段代码做了什么样的优化?

时间:2013-09-07 18:11:05

标签: clojure

我以为我会构建一个愚蠢的非尾递归版本的乘法函数,看看它与正确的TCO比较。但是我注意到REPL(我正在使用配置为java -cp <classpath> clojure.main的{​​{1}}的Emacs)以及从命令行调用程序时,显然正在进行某种优化/ memoization。实际上,结果在REPL中更为明显。

inferior-lisp

以上是在REPL上产生的:

  

用户=&GT; #'用户/ MULT傻
  用户=&GT; “经过的时间:10.697919 msecs”
  20000个
  “经过时间:3.069106 msecs”
  20000个
  “经过的时间:2.301474 msecs”
  20000个
  “经过的时间:1.285696 msecs”
  20000个
  “经过的时间:0.585541 msecs”
  20000

我知道为什么会看到这个?

1 个答案:

答案 0 :(得分:4)

正如@MariusDanila在评论中指出的那样,这是由于JIT的推动。

要验证这一点,您可以使用-Xint选项运行java,这会导致它运行 仅解释模式,因此没有任何内容编译为本机代码(当然也没有优化 完成该本机代码)。

所以这就是我正常运行java的原因:

"Elapsed time: 4.175 msecs"
20000
"Elapsed time: 2.548 msecs"
20000
"Elapsed time: 7.746 msecs"
20000
"Elapsed time: 1.919 msecs"
20000
"Elapsed time: 1.72 msecs"
20000

请注意,此处第三次运行实际上增加了时间。我想这是由于编译同时发生的。 然而,-Xint

"Elapsed time: 31.463 msecs"
20000
"Elapsed time: 30.844 msecs"
20000
"Elapsed time: 30.643 msecs"
20000
"Elapsed time: 29.972 msecs"
20000
"Elapsed time: 30.617 msecs"
20000

正如你在第二种情况中所看到的,没有加速。

这就是微基准测试的Rule 1始终排除测量的预热时间的原因。