Pythonでは、同じコードでも関数内で実行される場合と、関数外(グローバルスコープ)で実行される場合で速度が異なります。これは主に変数の管理方法に関連しており、関数内ではローカル変数が固定サイズの配列として管理されるのに対し、グローバル変数は辞書(ディクショナリ)を使ってアクセスされるため、後者はハッシュ検索のオーバーヘッドが発生します。

ローカル変数とグローバル変数の違い

関数内のローカル変数は、コンパイル時にサイズが固定されているため、直接配列から値を取得でき、アクセスが非常に速いです。対して、グローバル変数は辞書構造で管理されているため、変数の名前をハッシュ化し検索する必要があり、時間がかかります。 具体的なバイトコードを見ると、関数内のローカル変数にはSTORE_FAST命令が使われますが、グローバル変数にはSTORE_NAME命令が使われます。STORE_FASTは直接インデックスを指定してアクセスするのに対し、STORE_NAMEは名前で検索するため、パフォーマンスが低下します。

関数内での最適化

CPythonは、関数内でのローカル変数アクセスを高速化するために、最適化を行っています。具体的には、バイトコードの実行時に命令予測(opcode prediction)を行い、繰り返し実行されるループ内の命令を高速に処理します。この最適化により、関数内でのループ処理がさらに高速化されます。

結論

  • 関数内では、変数アクセスが配列ベースで行われるため、グローバルスコープでの辞書ベースのアクセスよりも高速です。
  • 関数内のコードは、特にループ処理がある場合、バイトコードの最適化によってさらに高速化されます。 これにより、Pythonでパフォーマンスを最大化したい場合、可能な限りコードを関数内にまとめることが推奨されます。