Python の速度が思ったより遅い
◆ 単純なループで JavaScript と比べて 100 倍以上遅かった
以前 JavaScript と Python で速度を比べたときはほとんど差はなかったのですがループ処理を比べるとかなり差が出ました
少し時間がかかる処理をブラウザ JavaScript で実行してるとタブが固まって不便だったので ブラウザじゃなくてコマンドとして実行しようとしました
その環境は Node.js がなかったので Python で書いたのですがいつになっても終わりません
Python コードに移植したときのバグかなと思ったのですがループ回数を減らすと問題なく動いていました
Node.js が入ってる環境で JavaScript と Python を両方実行してみると圧倒的に速度差がありました
色々コードを削って ほぼ単純なループだけになっても大きな差があるままだったので単純なループ処理だけでも遅いみたいです
100 万回ループしたら * を出力します
それを 10 回繰り返して終わりです
ループ前後で時刻を取得して経過時間を表示してます
Python に移植したものがこれです
数回やっても誤差程度です
それに比べて Python だと * がゆっくりひとつずつ出て 経過時間は 5.693 秒でした
こっちも数回やっても誤差程度です
実行したバージョンは
で Windows でやってます
ここまで差が出るはっきりとした原因はわかってませんが Python って数値もオブジェクトなので単純な足し算でも内部でメソッドが呼び出されたりで遅いのかなと思ってます
同じ回数のループを range を使った for 文で書いてみると 0.6 秒くらいになりました
Node.js より 10 倍近く遅いですが 元の Python よりは 10 倍近く速くなってます
上で書いたようなループ変数をインクリメントするようなループは基本は Python で書かないですけど 今回元々やりたかったものは「ループ回数は不明で条件を満たしたら抜ける」「抜けるまでのループ回数を数える」というのが必要なので while ループと変数のインクリメントになるのですよね
言語が選べるならこういう場合は Python 使わないほうがいいのかもしれません
少し時間がかかる処理をブラウザ JavaScript で実行してるとタブが固まって不便だったので ブラウザじゃなくてコマンドとして実行しようとしました
その環境は Node.js がなかったので Python で書いたのですがいつになっても終わりません
Python コードに移植したときのバグかなと思ったのですがループ回数を減らすと問題なく動いていました
Node.js が入ってる環境で JavaScript と Python を両方実行してみると圧倒的に速度差がありました
色々コードを削って ほぼ単純なループだけになっても大きな差があるままだったので単純なループ処理だけでも遅いみたいです
コード
JavaScript のコードはこれですlet i = 0
let j = 0
let d = Date.now()
while (j < 10) {
i++
if (i % 1000000 === 0) {
console.log("*")
j++
}
}
console.log("done")
console.log((Date.now() - d) / 1000)
100 万回ループしたら * を出力します
それを 10 回繰り返して終わりです
ループ前後で時刻を取得して経過時間を表示してます
Python に移植したものがこれです
import time
i = 0
j = 0
d = time.time()
while j < 10:
i += 1
if i % 1000000 == 0:
print("*")
j += 1
print("done")
print(time.time() - d)
結果
JavaScript の方では実行した瞬間に終了してるような速度で経過時間は 0.047 秒でした数回やっても誤差程度です
それに比べて Python だと * がゆっくりひとつずつ出て 経過時間は 5.693 秒でした
こっちも数回やっても誤差程度です
実行したバージョンは
>py -V
Python 3.8.1
>node -v
v12.6.0
で Windows でやってます
ここまで差が出るはっきりとした原因はわかってませんが Python って数値もオブジェクトなので単純な足し算でも内部でメソッドが呼び出されたりで遅いのかなと思ってます
同じ回数のループを range を使った for 文で書いてみると 0.6 秒くらいになりました
for j in range(10):
for i in range(1000000):
pass
print("*")
Node.js より 10 倍近く遅いですが 元の Python よりは 10 倍近く速くなってます
上で書いたようなループ変数をインクリメントするようなループは基本は Python で書かないですけど 今回元々やりたかったものは「ループ回数は不明で条件を満たしたら抜ける」「抜けるまでのループ回数を数える」というのが必要なので while ループと変数のインクリメントになるのですよね
言語が選べるならこういう場合は Python 使わないほうがいいのかもしれません