clojure - Clojure REPL 对这段代码做了什么样的优化?

标签 clojure

我想我会构建一个乘法函数的愚蠢的非尾递归版本,看看它如何与正确的 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
user=> "Elapsed time: 10.697919 msecs"
20000
"Elapsed time: 3.069106 msecs"
20000
"Elapsed time: 2.301474 msecs"
20000
"Elapsed time: 1.285696 msecs"
20000
"Elapsed time: 0.585541 msecs"
20000



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

最佳答案

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

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

所以这是我正常运行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微基准测试是始终从您的测量中排除预热时间。

关于clojure - Clojure REPL 对这段代码做了什么样的优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18676388/

相关文章:

jar - 'lein jar' 和 'lein uberjar' 没有正确设置主类

Clojure包含的范围? prime-seq 打印顶部素数

clojure - 如何在clojure中随机生成一个长数

clojure - 从列表创建 Compoju 路由

testing - Clojure 规范与基于属性的测试库(例如 Haskell QuickCheck)有何不同?

java - 如何使用 Maven 将 Clojure 依赖项包含到 Java 项目中

clojure - 我可以有条件地编译 clojure/clojurescript 吗?

jQuery 附加的 HTML 元素不会使用 crate 和 clj-js 获取 CSS 样式

java - 我在哪个目录运行 java -jar my-webapp-0.1.0-standalone.jar?

clojure - 有 Clojurescript 教程吗?