一般的にPythonはC/C++と比べて実行速度が遅いです。
・Pythonのようなインタプリタ言語はソースプログラムを機械語に翻訳しながら実行
・C/C++のようなコンパイル言語は実行前にあらかじめ機械語に翻訳するため実行
そのためPythonよりC/C++のほうが高速であることはよく言われることですが、それ以外にもPythonよりC/C++のほうが効率的な点があります。
Pythonのint型変数はイミュータブル
整数を表すint型変数は、C/C++ではミュータブル(変更可)ですが、Pythonではイミュータブル(変更不可)です。以下にC/C++とPythonのプログラム例を示します。
#include <iostream>
int main()
{
int a = 0;
std::cout << &a << std::endl ;
a = 10;
std::cout << &a << std::endl ;
}
0000003C7113FC80
0000003C7113FC80
上記C/C++プログラムでは、5行目で変数a
が生成され、そのアドレスは0000003C7113FC80
です。(6行目)
7行目でa
に10
を代入してもそのアドレスは変わらず0000003C7113FC80
です。(8行目)
a = 0
print(id(a))
a = 10
print(id(a))
2122483198224
2122483198544
上記Pythonプログラムでは、1行目で変数a
が生成され、そのアドレスは2122483198224
です。(2行目)
3行目でa
に10
を代入するとアドレスが2122483198544
に変わります。(4行目)
これは、1行目で生成したa
が破棄され、3行目で新たにa
が生成されていることを意味します。
for文のカウンタ変数では
次にfor文のカウンタ変数のアドレスも確認してみます。
#include <iostream>
int main()
{
int n = 10;
for ( int i = 0; i < n; ++i )
{
std::cout << &i << std::endl ;
}
return 0;
}
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
000000B3BE4FFCD0
上記C/C++プログラムではfor文で10回繰り返し処理を行っています。8行目でカウンタ変数i
のアドレスを表示しています。そのアドレスは10回とも000000B3BE4FFCD0
で変わっていません。
for i in range(10):
print(id(i))
1356276525328
1356276525360
1356276525392
1356276525424
1356276525456
1356276525488
1356276525520
1356276525552
1356276525584
1356276525616
上記Pythonプログラムではfor文のカウンタ変数i
のアドレスが変わっており、生成・破棄が繰り返されていることが確認できます。
Pythonのリスト内包表記を使用した場合も同様です。
[print(id(i), sep='\n') for i in range(10)]
1356276525328
1356276525360
1356276525392
1356276525424
1356276525456
1356276525488
1356276525520
1356276525552
1356276525584
1356276525616
i
は生成・破棄が繰り返されています。
まとめ
Pythonでは、たとえ同じint型変数に値を代入したときでも生成・破棄が行われます。この現象はパフォーマンスの低下を招きます。ほかにもfloat型、str型、bool型などはイミュータブルです。NumPyを使うなどして回避できることがありますので、プログラムを書く際は気をつけたいですね。
動作確認環境
Python:3.9.16
C/C++:Visual Studio 2019