【问题标题】:what kind of optimization is the Clojure REPL doing for this block of code?Clojure REPL 对这段代码做了什么样的优化?
【发布时间】:2013-09-07 18:11:04
【问题描述】:

我想我会构建一个愚蠢的非尾递归乘法函数版本,看看它与正确的 TCO 相比如何。但是我注意到,在 REPL(我使用 Emacs 和为java -cp <classpath> clojure.main 配置为inferior-lisp)和从命令行调用程序时,显然正在发生某种优化/记忆。事实上,结果在 REPL 中更为明显。

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

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

以上在 REPL 上产生:

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

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

【问题讨论】:

  • 可能是 JIT 编译器在起作用
  • 关闭。最有可能与自适应优化相结合(代码运行得越多,优化得越积极)。

标签: clojure


【解决方案1】:

正如@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 的微基准测试总是从您的测量中排除预热时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2022-06-28
    • 2018-08-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    相关资源
    最近更新 更多