1. ホーム
  2. python

[解決済み] Pythonのstrのパフォーマンス

2023-03-30 02:26:43

質問

Python コードの一部をプロファイリングしているとき ( python 2.6 まで 3.2 ) になっていることを発見しました。 str メソッドを使用してオブジェクト (私の場合は整数) を文字列に変換すると、文字列フォーマットを使用するよりもほぼ 1 桁遅くなることを発見しました。

以下はベンチマークです。

>>> from timeit import Timer
>>> Timer('str(100000)').timeit()
0.3145311339386332
>>> Timer('"%s"%100000').timeit()
0.03803517023435887

なぜこのようなことになるのか、どなたかご存知ですか? 私は何かを見逃しているのでしょうか?

どのように解決するのですか?

'%s' % 100000 はコンパイラによって評価され、実行時には定数と等価になります。

>>> import dis
>>> dis.dis(lambda: str(100000))
  8           0 LOAD_GLOBAL              0 (str)
              3 LOAD_CONST               1 (100000)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda: '%s' % 100000)
  9           0 LOAD_CONST               3 ('100000')
              3 RETURN_VALUE        

% を実行時表現で指定した場合は、(有意に)速くなることはありません。 str :

>>> Timer('str(x)', 'x=100').timeit()
0.25641703605651855
>>> Timer('"%s" % x', 'x=100').timeit()
0.2169809341430664

以下の点に注意してください。 str はまだ少し遅いです。@DietrichEpp が言ったように、これは str はルックアップと関数呼び出しの操作を含んでいるのに対し % は単一の即時バイトコードにコンパイルされます。

>>> dis.dis(lambda x: str(x))
  9           0 LOAD_GLOBAL              0 (str)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1
              9 RETURN_VALUE        
>>> dis.dis(lambda x: '%s' % x)
 10           0 LOAD_CONST               1 ('%s')
              3 LOAD_FAST                0 (x)
              6 BINARY_MODULO       
              7 RETURN_VALUE        

もちろん、上記は私がテストしたシステム(CPython 2.7)での話であり、他の実装は異なるかもしれません。