NetLogo的问题是否确保延迟评估?

时间:2016-12-26 17:35:25

标签: netlogo

以下两行代码有多相同?

ask agentset [if (attr > 0) [dosomething]]

ask agentset with [attr > 0] [dosomething]

是否有任何预期(和可解释的)差异 在速度或使用记忆? 特别是,在第二个中使用with case导致创建临时代理集, 或ask ... with组合确保 懒惰的评价?

2 个答案:

答案 0 :(得分:2)

只是为了扩展Nicolas说的话:

ask-with 故意不是懒惰。考虑代理正在修改其他代理的属性的代码,以确定是否应该询问它们,可以这么说:

to go
  ask patches with [ pcolor = red ] [
    ask neighbors4 [ set pcolor red ]
  ]
  tick
end

因为with创建了一个临时代理集,所以在询问期间不会更改询问的代理。这会导致红色区域在重复调用go时均匀生长:

enter image description here

现在,请考虑使用if

to go
  ask patches [ 
    if pcolor = red [
      ask neighbors4 [ set color red ]
    ]
  ]
  tick
end

由于尚未被问到的补丁可能会将其颜色更改为红色,因此红色区域会不均匀地增长:

enter image description here

因此,ask-with实际上有不同的行为然后询问 - 是否,因此无法优化它。也就是说,正如尼古拉斯所说,已经完成了一些类似的优化。

答案 1 :(得分:0)

(免责声明:我对编译器的熟悉程度非常肤浅,所以我可能会遗漏一些东西。)

NetLogo编译器执行的优化列表(可能已过时)可在此处获取:

https://github.com/NetLogo/NetLogo/wiki/Compiler-architecture#optimizer

这些(在NetLogo 6.0中)的实际代码在这里:

https://github.com/NetLogo/NetLogo/blob/bd3da2bf5495674ce5690cbb2992de4036c9db03/netlogo-core/src/main/compile/middle/optimize/package.scala

据我所知,ask ... with没有优化。这意味着ask ... with 创建了一个中间代理集,因此可能需要比ask ... [ if ... ]更多的内存和时间。

您应该使用哪一个可能取决于您对效率/可读性权衡的立场。 (我个人觉得ask ... with更具可读性。)

优化ask ... with会不是一个好主意?在我看来,绝对。话虽如此,在编写编译器时可能有技术原因不这样做。我只是不知道。

确实有一个很好的理由说明ask ... with未被优化。两个版本之间存在行为差异;它不仅仅是可读性与效率的关系。见布莱恩的回答。