遅いPythonを手を加えることなく一瞬で早くする方法あります
先に言うと、すみません、完全にタイトル詐欺です。でも手間を全くかけずに早くなるのはホントです。VScodeユーザ限定で、シーンも限定されますけどね。
やり方
VScodeではなく、シェルで実行する。
はい、たったこれだけです。
これで10倍くらいは早くなります。というかPython本来の性能になる、と言うのが正しいですね。
VScode使ってない方、タネに気づいている方、いやそもそもシェルで動かしてるしという方、ほんとごめんなさい。でも意外にこの思わぬ落とし穴に嵌った方もいるんじゃないでしょうか。私もその一人です。ではタネ明かししますね。
タネ明かし。犯人はあいつ
VScodeでPythonプログラムを動作させるとデバッグ機能が有効になるんですが、これがとてつもなく性能を阻害するんです。
VScodeで実行すると、ターミナルログをよく見ると作成したプログラムの他にdebugpy.pyというものが呼び出されているのが分かります。これがデバッグI/Fを実現しているんだと思うんですが、おそらくデバッグ対象のプログラムを読み込んで、一行ずつ解釈実行し、ブレイクの判定などしているのではないでしょうか。なのでVScodeで実行するととてつもなくPythonの性能が遅くなるというわけです。
そもそもデバッグ=性能問題を意識しろという指摘もあるかもしれませんが、TypeScriptの場合VScode上でもPythonより遥かに早いので、デバッガの影響になかなか思い至りませんでした。Python歴2ヶ月ほどですが、どうもPythonは大量のテキスト情報の処理に使っていてそもそも遅いという感じがしていました。
Pythonは遅い?
AIやデータマイニングの世界でPythonはよく使用されていると聞くので、勝手なイメージでよもや性能とか問題になるとは思ってもみなかったんですが、ググってみるとどうやらPythonってスクリプト言語の中ではとても遅いと評判のようです。実際とある記述を処理するパーサーをPythonとTypescriptコードで出力して動作比較したところ、処理にかかる時間がTypescriptに対し2〜6倍程度遅くなる傾向がありました。
そもそも素の状態でこれだけの性能差があるのでVScodeのデバッガ上で動かした時の遅さときたらとんでもなかったわけです。
本当にPythonを早くする方法
ほぼ手間をかけずに性能改善をするにはPyPyが良いようです。公式サイトによると4倍早いとありますが、実際先程のパーサーをPyPyで動作させたところ2〜6倍程度改善が見られました。
ただしPyPyを使用するにあたりいくつか注意点があります。
PyPy最新版v7.3.5はPython3.7準拠であるため、元々の作成したプログラムがPython3.7以降の機能を使用している場合は修正が必要になります。
また詳細は読んでいませんが、CPython(Pythonのリファレンス実装でいわゆるいつものPython)と動作差分があるようなのでPyPy.orgのPython Compatibilityを確認しておいた方が良いでしょう。
私が使った範囲で気づいたのはC言語で記述されたモジュールは使用できないようです。例えばujsonがそうですね。使用するとWindowsErrorの例外が発生しました。どうやらABIの互換性の問題のようですが、先ほどのPython CompatibilityのページによるとPyPy向けにリコンパイルすれば使えるようです。しかし、外部パッケージや外部パッケージの依存パッケージにC言語で実装されたモジュールが存在する場合は問題となります。この辺りパッケージマネージャなどで外部パッケージの依存パッケージを細かくインストール制御できないでしょうか?
VScodeのPyPyサポート
VSCodeの最新版はPyPyをサポートしているようです。
PythonではなくPyPyをインタプリタとして使用する場合、VScodeの左下に表示されているPythonのインタプリタバージョンをクリックするとインタプリタを設定できるようになり、PyPy3.exeのパスを指定してあげます。これによりPyPy3でデバッグできるようになりますが、使用したところいくつか問題がありました。
一つはデバッガを起動するとデバッグプロセスが死にましたとエラー表示されました。無視してキャンセルして続行すると、特に問題なくデバッグできているようです。謎です。
最後に、ソースコードのパスに日本語が含まれているとデバッガの起動に失敗します。こちらはどうやってもデバッグできません。安全な場所にプロジェクトフォルダを移動させましょう。