示例说明了一切:
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
答案 0 :(得分:5)
我相信编译器会内联某些核心函数,例如inc
,尤其是在应用于原始参数时。
当您使用inc
作为常规函数时(例如,传递给更高阶函数,使用let
别名等),因此性能可能会更差,因为它会失去内联功能。额外的开销来自于进行额外的函数调用,也可能是装箱一个或多个参数的成本。
这不是Clojure的限制,只是反映了编译器在优化方面还不是很复杂的事实。你可以期待这样的事情在未来的Clojure版本中变得更好。
答案 1 :(得分:5)
只是添加mikera提到的关于内联的内容。 inc
是绑定到函数的var。如果你查看var meta
的{{1}}即inc
,你会发现它有一个键(meta #'inc)
,其编码器可以使用它来内联函数的代码它被称为使用inc var 。当你使用:inliner
在本地绑定它时,你只是将函数对象绑定到本地范围内的新名称,而函数对象没有任何内联信息,let
var就是这样的info,因此编译器无法内联它。