もう1つの要因は、TaskA
が呼び出される前に実行される「準備」/セットアップです。可能であればf1
でfor
ループの前に1回行ってからf3
で完了し、x in X
からf2
に1回だけではなく1回呼び出される可能性があります。実際のコードがなければ、言うことは難しいです。
x
ごとにf3
を呼び出す潜在的な複雑さは、それが10倍の遅さの原因であるとは考えられません。
pass
の簡略化された例でのみ、この現象があります。ここでのバイトコードがf1
のための次のようになります、dis
を使用して
>>> def f1():
... for x in X:
... pass
...
>>> def f2():
... for x in X:
... f3()
...
>>> def f3():
... pass
...
:
>>> dis.dis(f1)
2 0 SETUP_LOOP 14 (to 17)
3 LOAD_GLOBAL 0 (X)
6 GET_ITER
>> 7 FOR_ITER 6 (to 16)
10 STORE_FAST 0 (x)
3 13 JUMP_ABSOLUTE 7
>> 16 POP_BLOCK
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
...対f2
:
>>> dis.dis(f2)
2 0 SETUP_LOOP 21 (to 24)
3 LOAD_GLOBAL 0 (X)
6 GET_ITER
>> 7 FOR_ITER 13 (to 23)
10 STORE_FAST 0 (x)
3 13 LOAD_GLOBAL 1 (f3)
16 CALL_FUNCTION 0
19 POP_TOP
20 JUMP_ABSOLUTE 7
>> 23 POP_BLOCK
>> 24 LOAD_CONST 0 (None)
27 RETURN_VALUE
のは
f1
、
f2
と
f3
のこれら3つの悪いのバージョンを見てみましょう
これらは、を除いてほぼ同じです10およびPOP_TOP
。しかし、彼らはtimeit
と非常に異なっている:
>>> X = range(1000) # [0, 1, 2, ...999]
>>>
>>> import timeit
>>> timeit.timeit(f1)
10.290941975496747
>>> timeit.timeit(f2)
81.18860785875617
>>>
今では時間の8倍だがない関数を呼び出すことは遅いあるので、しかし、forループf1
年代にpass
が、何もしないことは、特に、非常に高速であるため、 を呼び出すと、毎回関数が呼び出され、何もしません。だからうまくいけばではないこれらを例として使って/ wonderを調べる理由。今
、x * x
はその後、次の2つの間のタイミング/パフォーマンスの差が小さくなって表示されます言うようにあなたが実際には、タスクで何かをすれば:今では唯一の2.9xだ
>>> def f1():
... for x in X:
... _ = x*x
...
>>> def f2():
... for x in X:
... _ = f3(x) # didn't pass in `x` to `f3` in the previous example
...
>>> def f3(x):
... return x*x
...
>>> timeit.timeit(f1)
38.76545268807092
>>> timeit.timeit(f2)
113.72242594670047
>>>
時間。遅れを引き起こす関数呼び出し(ある程度のオーバーヘッドがあります)だけでなく、関数内で何をしているのかは、全体の時間に違いをもたらすpass
です。
あなたはかなりの「遅い」、そしてちょうどX = range(5)
である、両方の場所でprint x * x
で_ = x * x
を交換する場合:
>>> timeit.timeit(f1, number=10000)
3.640433839719143
>>> timeit.timeit(f2, number=10000)
3.6921612171574765
そして今、彼らのパフォーマンスのあまり違いがあります。
単純な擬似コード分析だけでなく、実際のコードで実際のチェックを行います。空の呼び出しは速く表示されるかもしれませんが、そのオーバーヘッドは実際には遅いものののコードでは機能しません。
あなたが恐ろしい擬似コードインタープリタを使用しているので、明らかにこの擬似コードは遅いです...実際に**コードを投稿することを考えましたか? –
あなたは関数呼び出しが文字通り唯一の違いであるコードを私たちに与えています。おそらく到達できる唯一の結論は、「関数呼び出しは遅い」ということです。関数呼び出しが(顕著に)遅くないという事実は、実際にコードの関連部分を投稿していないことを示しています。 ['cProfile.run( 'f2()')'](https://docs.python.org/2/library/profile.html) –