エージェントベースのシミュレーション:パフォーマンスの問題:PythonとNetLogo&Repast

StackOverflow https://stackoverflow.com/questions/4905873

質問

Python 3でSugarscapeエージェントシミュレーションモデルの一部を複製しています。コードのパフォーマンスは、NetLogoのパフォーマンスの約3倍遅いことがわかりました。コードに問題がある可能性がありますか、それともPythonに固有の制限である可能性がありますか?

明らかに、これはコードの断片にすぎませんが、Pythonが実行時間の3分の2を費やしている場所です。本当に非効率的なものを書いた場合、それがこのフラグメントに表示されることを願っています: ジェネラコディセタグプレ

ほぼ同等の NetLogoのコード(このフラグメントは上記のPython関数よりも少し多くの機能を果たします) : ジェネラコディセタグプレ

私のコンピューターでは、Pythonコードは1000ステップを実行するのに15.5秒かかります。同じラップトップで、ブラウザ内のJavaで実行されているNetLogoシミュレーションは、6秒未満で1000ステップを完了します。

編集:Java実装を使用して、Repastをチェックしました。また、5.4秒のNetLogoとほぼ同じです。 JavaとPythonの最近の比較は、Javaに利点がないことを示唆しています、だから私は自分のコードだけが原因だと思いますか?

編集: MASON はよりも高速であると思われることを理解しています過去にさかのぼりますが、それでも最終的にはJavaを実行します。

役に立ちましたか?

解決

This probably won't give dramatic speedups, but you should be aware that local variables are quite a bit faster in Python compared to accessing globals or attributes. So you could try assigning some values that are used in the inner loop into locals, like this:

def look_around(self):
    max_sugar_point = self.point
    max_sugar = self.world.sugar_map[self.point].level
    min_range = 0

    selfx = self.point[0]
    selfy = self.point[1]
    wlength = self.world.surface.length
    wheight = self.world.surface.height
    occupied = self.world.occupied
    sugar_map = self.world.sugar_map
    all_directions = self.all_directions

    random.shuffle(all_directions)
    for r in range(1, self.vision+1):
        for dx,dy in all_directions:
            p = ((selfx + r * dx) % wlength,
                (selfy + r * dy) % wheight)
            if occupied(p): # checks if p is in a lookup table (dict)
                continue
            if sugar_map[p].level > max_sugar:
                max_sugar = sugar_map[p].level
                max_sugar_point = p
    if max_sugar_point is not self.point:
        self.move(max_sugar_point)

Function calls in Python also have a relatively high overhead (compared to Java), so you can try to further optimize by replacing the occupied function with a direct dictionary lookup.

You should also take a look at psyco. It's a just-in-time compiler for Python that can give dramatic speed improvements in some cases. However, it doesn't support Python 3.x yet, so you would need to use an older version of Python.

他のヒント

I'm going to guess that the way that neighborhood is implemented in NetLogo is different from the double loop you have. Specifically, I think they pre-calculate a neighborhood vector like

n = [ [0,1],[0,-1],[1,0],[-1,0]....]

(you would need a different one for vision=1,2,...) and then use just one loop over n instead of a nested loop like you are doing. This eliminates the need for the multiplications.

I don't think this will get you 3X speedup.

This is an old question, but I suggest you look into using NumPy for speeding up your operations. Places where you use dicts and lists which are logically organized (1-, 2-, 3-, or N-dimensional grid) homogenous data object (all integers, or all floats, etc) will have less overhead when represented and accessed as Numpy arrays.

http://numpy.org

Here is a relatively up to date comparison of NetLogo and one version of Repast. I would not necessarily assumed Repast is faster. NetLogo seems to contain some very smart algorithms that can make up for whatever costs it has. http://condor.depaul.edu/slytinen/abm/Lytinen-Railsback-EMCSR_2012-02-17.pdf

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top