0

質問は本当にタイトルが何を言っているのかです。


質問の理由: mapfunc はfor、以下のコードのループよりも遅いです。
私のコードに何らかの問題があるためですか、それとも他に何かありますか??

コード:

import timeit

setup = '''
def translate(x):
    x[1]+=1
    x[2]+=1
    x[3]+=1

atoms = [[1,1,1,1]]*1000
'''
smt1 = '''for i in atoms: translate(i)'''
smt2 = '''map(translate, atoms)'''

time_for = timeit.Timer(setup=setup, stmt=smt1)
time_map = timeit.Timer(setup=setup, stmt=smt2)

print time_for.timeit(10000)
print time_map.timeit(10000)

出力 (Windows 7 (64 ビット) I-3 第 2 世代):

>>> 
3.4691164256
3.5064888507

出力 (Windows 7 (32 ビット) core2duo):

>>>
5.58571625252
6.25803459664

私はPython 2.7.3を使用していることに言及する必要があると思います.Python map3ではジェネレーターですが、Python 2ではそうではないため、この「問題」はPython 3では再現できません.


アップデート:

アトムは不変であるべきだと言った人たちに対処するために、別のバージョンのセットアップを次に示します (速度は遅くなりますが、それでも違いが示されます)。

setup = '''
def translate(x):
    return tuple(i+1 for i in x)

atoms = [(1,1,1,1)]*1000
'''

出力 (Windows 7 (32 ビット) core2duo):

>>> 
31.0213507144
29.7194933508
4

5 に答える 5

5

これはmap、新しい構造を作成するのに対しfor、現在の構造のみを変更するためです。

于 2013-04-26T13:36:33.397 に答える
4

いくつかの観察。

  • 通常、それは悪い考えです[[1,1,1,1]]*n。これにより、同じリストnへの参照が作成されます。不変であるため、実行しても問題ありません。[None]*nNone
  • ループではなくマップでリストを作成しています。これにより、いくらかのオーバーヘッドが発生します
  • 別のオプションがあります (リスト コンプ)

import timeit

setup = '''
def translate(x):
    x[1]+=1
    x[2]+=1
    x[3]+=1

atoms = [[1,1,1,1] for _ in range(1000) ]
'''
smt1 = '''lst = []
for i in atoms: lst.append(translate(i))'''
smt2 = '''map(translate, atoms)'''
smt3 = '''[translate(i) for i in atoms]'''

time_for = timeit.Timer(setup=setup, stmt=smt1)
time_map = timeit.Timer(setup=setup, stmt=smt2)
time_lc  = timeit.Timer(setup=setup, stmt=smt3)

print time_for.timeit(10000)
print time_map.timeit(10000)
print time_lc.timeit(10000)

とは言うものの。map私にとってはまだ遅いです

7.49916100502
7.83171486855
6.13082003593

そして、リストの理解が勝ります。

ただし、スタイルのポイントとして、forここでは間違いなくループを使用します。から何も返さないためtranslate、これが最もクリーンな代替手段です。「副作用」にmapandを使用することは、一般的に推奨される方法ではありません。list-comprehensions

于 2013-04-26T13:42:03.257 に答える
0

Python 3.3 で結果を複製できません (両方ともmap、リストではなく遅延反復子rangeを返すようになりました):

In [7]: %timeit list(map(lambda x: x + 1, range(1000)))
1000 loops, best of 3: 218 us per loop

In [8]: %timeit [x + 1 for x in range(1000)]
10000 loops, best of 3: 99.5 us per loop
于 2013-04-26T13:39:52.523 に答える