Python で timeit モジュール (編集: Python 3 を使用しています) を使用して、いくつかの異なるコード フローを決定しようとしています。このコードには、文字列内に文字コードが存在するかどうかをテストする一連の if ステートメントがあり、存在する場合は次のように置き換えます。
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
これをさまざまな部分文字列に対して何度も行います。それと、次のような置換のみを使用することとの間で議論しています。
str_var = str_var.replace("<substring>", "<new_substring>")
timeit を使用して、どちらが高速かを判断しようとしました。上記の最初のコード ブロックが「stmt1」で 2 番目が「stmt2」の場合、セットアップ文字列は次のようになります。
str_var = '<string><substring><more_string>',
timeit ステートメントは次のようになります。
timeit.timeit(stmt=stmt1, setup=setup)
と
timeit.timeit(stmt=stmt2, setup=setup)
さて、同じように実行すると、2台のラップトップ(同じハードウェア、同様の処理負荷)でstmt1(ifステートメントを含むステートメント)が複数回実行した後でも高速に実行されます(100分の3〜4秒対約4分の1秒) stmt2 の 1 秒)。
ただし、両方のことを行う関数を定義すると (変数を作成するセットアップを含む)、次のようになります。
def foo():
str_var = '<string><substring><more_string>'
if "<substring>" in str_var:
str_var = str_var.replace("<substring>", "<new_substring>")
と
def foo2():
str_var = '<string><substring><more_string>'
str_var = str_var.replace("<substring>", "<new_substring>")
実行時は次のようになります。
timeit.timeit("foo()", setup="from __main__ import foo")
timeit.timeit("foo2()", setup="from __main__ import foo2")
if ステートメントのないステートメント (foo2) はより高速に実行され、関数化されていない結果と矛盾します。
Timeit の仕組みについて何か不足していますか? または、Python はこのようなケースをどのように処理しますか?
実際のコードは次のとおりです。
>>> def foo():
s = "hi 1 2 3"
s = s.replace('1','5')
>>> def foo2():
s = "hi 1 2 3"
if '1' in s:
s = s.replace('1','5')
>>> timeit.timeit(foo, "from __main__ import foo")
0.4094226634183542
>>> timeit.timeit(foo2, "from __main__ import foo2")
0.4815539780738618
対このコード:
>>> timeit.timeit("""s = s.replace("1","5")""", setup="s = 'hi 1 2 3'")
0.18738432400277816
>>> timeit.timeit("""if '1' in s: s = s.replace('1','5')""", setup="s = 'hi 1 2 3'")
0.02985000199987553