2

簡単なパフォーマンス テストを行っていたところ、リストを一般的に初期化すると、明示的に初期化するよりも約 4 倍から 6 倍遅いことに気付きました (これらはおそらく用語が間違っているため、ここでの用語についてはよくわかりません)。例えば:

>>> import timeit
>>> print timeit.timeit('l = list()', number = 10000000)
1.66420578957
>>> print timeit.timeit('l = []',     number = 10000000)
0.448561906815

タプルと int についても同様です。

>>> print timeit.timeit('l = tuple()', number = 10000000)
1.10791182518
>>> print timeit.timeit('l = ()',      number = 10000000)
0.23167181015

>>> print timeit.timeit('l = int()', number = 10000000)
1.3009660244
>>> print timeit.timeit('l = 0',     number = 10000000)
0.232784032822

どうしてこれなの?

4

3 に答える 3

8

dis モジュールを使用してバイトコードを検査します。

import dis        
dis.dis(lambda: list())

収量

  6           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 RETURN_VALUE        

その間

dis.dis(lambda: [])

収量

  7           0 BUILD_LIST               0
              3 RETURN_VALUE        

list()そのため、グローバル名を検索してオブジェクトを呼び出す必要がありますが、そうではありませ[]ん。

于 2012-12-21T13:45:16.033 に答える
2

これは、Python がリテラル構文を使用して、1 つのバイトコードでリストを構築することを知っているためです。コンストラクターを呼び出すには、listグローバルを検索して代わりに呼び出す必要があります。

>>> def foo(): []
... 
>>> dis.dis(foo)
  1           0 BUILD_LIST               0
              3 POP_TOP             
              4 LOAD_CONST               0 (None)
              7 RETURN_VALUE        
>>> def bar(): list()
... 
>>> dis.dis(bar)
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 POP_TOP             
              7 LOAD_CONST               0 (None)
             10 RETURN_VALUE        
于 2012-12-21T13:44:44.690 に答える
2

異なるバイトコード。list()例としてvsを取る[]

l = list():
  1           0 LOAD_GLOBAL              0 (list)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (l)

l = []:
  1           0 BUILD_LIST               0
              3 STORE_FAST               0 (l)

前者には、名前の検索"list"と関数呼び出しが含まれます。

于 2012-12-21T13:45:48.967 に答える