简体   繁体   English

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

[英]what kind of optimization is the Clojure REPL doing for this block of code?

I thought I would build a silly non-tail-recursive version of a multiplication function and see how it compares against the proper TCO one. 我以为我会构建一个愚蠢的非尾递归版本的乘法函数,看看它与正确的TCO比较。 However I noticed that both at the REPL (I am using Emacs with java -cp <classpath> clojure.main configured for inferior-lisp ) and when invoking the program from the command line some kind of optimization / memoization is apparently taking place. 但是我注意到两者都在REPL(我使用Emacs, java -cp <classpath> clojure.maininferior-lisp配置),并且当从命令行调用程序时,显然正在进行某种优化/ memoization。 In fact the results are much more pronounced in the REPL. 实际上,结果在REPL中更为明显。

(defn mult-silly [n m]
  (if (> n 0)
    (+ m (mult-silly (dec n) m))
    0))

(dotimes [_ 5]
  (println (time (mult-silly 5000 4)))) 

The above produces on the REPL: 以上是在REPL上产生的:

user=> #'user/mult-silly user =>#'user / mult-silly
user=> "Elapsed time: 10.697919 msecs" user =>“经过的时间:10.697919 msecs”
20000 20000
"Elapsed time: 3.069106 msecs" “经过的时间:3.069106 msecs”
20000 20000
"Elapsed time: 2.301474 msecs" “经过的时间:2.301474毫秒”
20000 20000
"Elapsed time: 1.285696 msecs" “经过的时间:1.285696 msecs”
20000 20000
"Elapsed time: 0.585541 msecs" “经过的时间:0.585541毫秒”
20000 20000

Any idea why I see this? 知道我为什么看到这个吗?

As @MariusDanila pointed out in his comment, this is due to the JIT kicking in. 正如@MariusDanila在他的评论中指出的那样,这是由于JIT踢了。

To verify this you can run java with the -Xint option, which causes it to run in interpreted-only mode, so nothing is compiled to native code (and surely no optimizations are done to that native code). 要验证这一点,您可以使用-Xint选项运行java,这会导致它以仅解释模式运行,因此不会将任何内容编译为本机代码(当然也不会对该本机代码进行优化)。

So here's what I got running java normally: 所以这就是我正常运行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

Note that here the time actually increased for the third run. 请注意,这里第三次运行的时间实际上增加了。 I guess this due to compilation occurring concurrently. 我想这是由于编译同时发生的。 Whereas, with -Xint : 然而,使用-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

As you can see in the second case there is no speedup. 正如你在第二种情况中看到的那样,没有加速。

This is why Rule 1 for microbenchmarking is to always exclude warmup times from your measurements. 这就是为什么微尺度标记的规则1总是要从测量中排除预热时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM