谁能解释为什么以下两个部分之间存在性能差异?第二个定时器调用报告的数字比第一个定时器调用报告的数字小,这在统计上很重要。我唯一的想法是 Netlogo 可以将海龟缓存在内存中。这是预期的行为还是有错误?
to setup
clear-all
crt 100
let repetitions 10000
;;Timing assigning x to self
reset-timer
repeat repetitions
[
ask turtles
[
let x self
]
]
show timer
;;Timing assigning x to who of self
reset-timer
repeat repetitions
[
ask turtles
[
let x [who] of self
]
]
show timer
end
最佳答案
这不是因为 NetLogo 本身的任何东西,而是因为 NetLogo 在 JVM 上运行。 JVM 学习优化代码,将其作为 just-in-time compilation (JIT) 的一部分运行得越多。
到第二段运行时,JVM 已经有时间优化两个段共有的许多代码路径。确实,切换段的顺序,我得到了以下结果:
observer> setup
observer: 0.203
observer: 0.094
observer> setup
observer: 0.136
observer: 0.098
observer> setup
observer: 0.13
observer: 0.097
observer> setup
observer: 0.119
observer: 0.095
observer> setup
observer: 0.13
observer: 0.09
现在
let x self
代码更快了(它现在是第二个运行的东西)!另请注意,我运行的越多,这两个时间都会减少 setup
。这也是由于 JVM 的 JIT。同样,如果我关闭 View 更新并运行您的原始代码,我会得到:
observer> setup
observer: 0.088
observer: 0.071
observer> setup
observer: 0.094
observer: 0.072
observer> setup
observer: 0.065
observer: 0.075
observer> setup
observer: 0.067
observer: 0.071
observer> setup
observer: 0.067
observer: 0.068
let x self
代码开始较慢(出于上述原因),然后变得与人们预期的速度大致相同。关于为什么只有在关闭 View 更新时才会发生这种情况的原因有很多。 NetLogo 在关闭 View 更新的情况下做得更少JVM 的 JIT 是极其优化的,但很复杂,而且很难推理。 There's a lot to consider if you want to write truly correct micro-benchmarks.
关于benchmarking - Netlogo 中的时间差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36253959/