1

私は現在、座標xを何度も変換するソフトウェアの翻訳部分を最適化しているところです。私の現在の翻訳コードは関数内にあり、translate関数内のおそらく最適化された部分translate_mapです。

ここで、ループはCで実行されるため、可能な場合はループの代わりに関数を使用する必要があることを読みました.mapfor

以下のテスト ケースを実行すると、関数は実際には標準のループmapよりも遅く実行されます。従来のループよりもパフォーマンスが遅いforのはなぜですか? 翻訳機能を最適化してより高速に実行するにはどうすればよいですか?mapfor

import time

def translate(atom_list):
    for i in atom_list:
        i[1]+=1
        i[2]+=1
        i[3]+=1

atoms = [[1,1,1,1]]*1000
start = time.time()
for x in xrange(10000):
    translate(atoms)
print time.time() - start


atoms = [[1,1,1,1]]*1000
start = time.time()
def translate_map(atom_list):
    atom_list[1]+=1
    atom_list[2]+=1
    atom_list[3]+=1
for x in xrange(10000):
    map(translate_map,atoms)
print time.time() - start

出力:

2.92705798149
4.14674210548
4

1 に答える 1

3

実装で見られるオーバーヘッドのほとんどは、map関数呼び出しのオーバーヘッドによるものだと思います。このtranslate関数はすべての作業を 1 つのループ内で実行するため、プロセス全体で 1 つの関数呼び出しのみが行われます。を使用した実装でmapは、リスト内のすべての項目に対して個別の関数呼び出しが行われます。

オーバーヘッドの 2 つ目の原因 (関数呼び出しに比べれば小さいとは思いますが) はmap、関数からの戻り値を含むリストを作成することです。translate_mapにはステートメントがないためreturn、これはすべてのNone値になります。Python 3 では、mapはジェネレーターであるため、呼び出しmapの結果を繰り返し処理しない限り、バージョンはまったく機能しないことに注意してください。mapただし、明示的なループの方がはるかに明確なので、それを使い続けます (numpy を使用しない場合)。

ああ、そうです、numpyこれははるかに簡単になります (そしてほぼ確実に速くなります):

def translate(arr): # arr should be a numpy array
    arr += 1

それでおしまい!ループは必要ありません (Python レベルで)。

于 2013-04-26T10:43:10.903 に答える