10

这个例子说明了一切:

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
4

2 回答 2

5

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

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

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

于 2013-06-06T02:30:55.340 回答
5

只是为了补充 mikera 提到的关于内联的内容。Theinc是绑定到函数的 var。如果您查看metaof var incie (meta #'inc),您会发现它有一个键,编译器可以使用其值来内联使用 inc var:inliner调用它的函数的代码。当您使用在本地绑定它时,您只是将函数对象绑定到本地范围内的新名称,并且函数对象没有任何内联信息,它是具有该信息的 var,因此编译器无法内联它。letinc

于 2013-06-06T04:32:10.797 回答