1. ホーム
  2. python

[解決済み] Pythonは戻り値としてのみ使われる変数を最適化するのですか?

2022-11-14 05:55:45

質問

次の2つのコードに究極の違いはあるか。最初のものは、関数内の変数に値を代入し、その変数を返します。2番目の関数は、単に値を直接返します。

Pythonはそれらを同等のバイトコードに変換しますか?どちらかが速いのでしょうか?

ケース1 :

def func():
    a = 42
    return a

ケース2 :

def func():
    return 42

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

いいえ。 それはありません .

CPythonのバイトコードへのコンパイルは、小さな ピーポーオプティマイザ これは基本的な最適化のみを行うように設計されています ( test_peepholer.py を参照してください)。

実際に何が起こっているのかを見るために dis * を使って、生成される命令を見てみましょう。最初の関数について、代入を含む。

from dis import dis
dis(func)
  2           0 LOAD_CONST               1 (42)
              2 STORE_FAST               0 (a)

  3           4 LOAD_FAST                0 (a)
              6 RETURN_VALUE

一方、2番目の関数については

dis(func2)
  2           0 LOAD_CONST               1 (42)
              2 RETURN_VALUE

1ではさらに2つの(高速)命令が使用されています。 STORE_FAST LOAD_FAST . これらは fastlocals 配列の値を素早く保存し、取得します。次に、どちらの場合も RETURN_VALUE が実行されます。つまり、2番目はこれまで わずかに 実行に必要なコマンドが少なくなるため、より速くなります。

一般に、CPythonコンパイラは 保守的 であることに注意してください。そうではなく になろうとはしません。 は、他のコンパイラ(一般に、コンパイラは作業するためにはるかに多くの情報を持っています)ほどスマートではありませんし、そうなろうともしていません。主な設計目標は、明らかに正しいことを除けば、a) シンプルであること、b) コンパイル時にできるだけ迅速に行い、コンパイル段階が存在することに気づかないようにすること、です。

結局のところ、このような小さな問題で悩むべきではありません。速度の利点は小さく、一定で、Pythonがインタプリタであるという事実によってもたらされるオーバーヘッドによって矮小化されます。

* dis はコードをディスアセンブルする小さな Python モジュールで、これを使うと VM が実行する Python バイトコードを見ることができます。

注意してください。 Jorn Vernee のコメントにもあるように、これは CPython による Python の実装に特有のものです。他の実装が望めば、より積極的な最適化を行うかもしれませんが、CPython では行いません。