基于代理的仿真:性能问题:Python与NetLogo和Repast
-
29-10-2019 - |
题
我正在Python 3中复制一小段Sugarscape代理仿真模型。我发现我的代码性能比NetLogo慢3倍左右。是我的代码可能有问题,还是Python的固有局限性?
很显然,这只是代码的一部分,但是那是Python花费三分之二的运行时间的地方。我希望如果我写的东西效率真的很低,它可能会出现在以下片段中: 通用标签
大致等效的 NetLogo中的代码(此片段的功能比上面的Python函数还要多) : 通用标签
在我的计算机上,Python代码需要15.5秒才能运行1000个步骤;在同一台笔记本电脑上,在浏览器内部以Java运行的NetLogo仿真可以在不到6秒的时间内完成1000个步骤。
编辑:刚刚检查了Repast,使用Java实现。而且它与5.4秒的NetLogo大致相同。 Java和Python之间的最近的比较表明Java没有优势,所以我猜这应该只是我的代码?
编辑:我了解 MASON 应该比Repast,但最终还是运行Java。
解决方案
这可能不会显着提高速度,但是您应该意识到,与访问全局变量或属性相比,Python中的局部变量要快得多。因此,您可以尝试将内部循环中使用的一些值分配给本地变量,如下所示: 通用标签
Python中的函数调用也具有相对较高的开销(与Java相比),因此您可以尝试通过直接字典查找替换occupied
函数来进一步优化。
您还应该查看 psyco 。它是用于Python的即时编译器,在某些情况下可以显着提高速度。但是,它尚不支持Python 3.x,因此您需要使用旧版本的Python。
其他提示
我猜想Netraco中实现neighborhood
的方式与您的双循环不同。具体来说,我认为他们预先计算了类似的邻域矢量
通用标签
(对于vision= 1,2,...您将需要一个不同的循环),然后仅对n
使用一个循环,而不是像您所做的那样使用嵌套循环。这样就不需要乘法了。
我认为这不会使您的速度提高3倍。
这是一个古老的问题,但是我建议您考虑使用NumPy来加快操作速度。当使用表示为Numpy的形式访问的字典和列表(按一维,2-维,3-维或N维网格)同质数据对象(所有整数或所有浮点数等)时,其开销较小数组。
这是NetLogo和Repast的一个版本的相对最新的比较。我不一定会假设Repast更快。NetLogo似乎包含一些非常聪明的算法,可以弥补所拥有的任何成本。 http://condor.depaul.edu/slytinen/abm/Lytinen-Railsback-EMCSR_2012-02-17.pdf