如果没有本地绑定,核心中的函数如何运行得更快?

时间:2013-06-05 22:09:39

标签: optimization clojure

示例说明了一切:

user> (time (dotimes [i 10000000] (inc i)))
"Elapsed time: 413.948711 msecs"
nil
user> (time (let [new-inc inc] (dotimes [i 10000000] (new-inc i))))
"Elapsed time: 1034.722729 msecs"
nil

2 个答案:

答案 0 :(得分:5)

我相信编译器会内联某些核心函数,例如inc,尤其是在应用于原始参数时。

当您使用inc作为常规函数时(例如,传递给更高阶函数,使用let别名等),因此性能可能会更差,因为它会失去内联功能。额外的开销来自于进行额外的函数调用,也可能是装箱一个或多个参数的成本。

这不是Clojure的限制,只是反映了编译器在优化方面还不是很复杂的事实。你可以期待这样的事情在未来的Clojure版本中变得更好。

答案 1 :(得分:5)

只是添加mikera提到的关于内联的内容。 inc是绑定到函数的var。如果你查看var meta的{​​{1}}即inc,你会发现它有一个键(meta #'inc),其编码器可以使用它来内联函数的代码它被称为使用inc var 。当你使用:inliner在本地绑定它时,你只是将函数对象绑定到本地范围内的新名称,而函数对象没有任何内联信息,let var就是这样的info,因此编译器无法内联它。