Last Updated: 2/6/2024, 5:44:57 AM

# 禁則事項

ここに書かれていることを
意識してコーディング
しないでください

ここで書かれていることを気にして、コーディングしない方が望ましいです。 ここで書かれていることは Python を高速化するための tips というよりも Python の動作とか性質が、 だいたいどんなものかを理解するためのものと捉えていただけると嬉しいです。

もし処理速度を本当に向上させたい場合は、 いくつかやり方があるように感じます。

  1. cProfile などを使い遅い場所を特定する。
  2. より良いアルゴリズム、データ構造を検討、採用する。
  3. Numba など外部ライブラリの利用する。
  4. 処理を並列化する。
  5. PyPy を使う。
  6. Cython を使って CPython を拡張する(C 言語で書き直したりする)
  7. Go などの全く別言語に書き換える。

特に Python で書くときは、高速化よりも可読性を重視した方が望ましいと感じます。理由は2つあります。

# 1つ目の理由

1つ目は Python は、コードをささっと書き上げることを目的にしているからです。 実行時間を速くすることを目的にしていません。パフォーマンスよりも可読性を優先した例としては、 型にとらわれず自由にプログラミングできるように静的型付けではなく動的型付けを採用したこと、 自由にオブジェクトの属性を追加できるようにしたため属性参照のコストが重くなっていること。

私にとって重要なのは、どうすれば生産性の高い仕事ができるかなのです。 ”生産性”とは何か。私の場合、分析は1回しか行いません(異なるアイデアのテストやデバッギングは別です)。 ある特定のコードを24時間実行することもありません。私はエンドユーザのためのソフトウェアアプリを開発していません。

私は”生産性”を定量化する際、(1)アイデアをコードで書き出す時にかかった時間、(2)デバッギングにかかった時間、 (3)実行にかかった時間の合計時間を想定します。 私にとって”高い生産性”は”結果を出すまでにかかった時間”を意味します。長年の経験から、自分にはPythonが合っていることが分かりました。

「塩を取って」

「だからさ……」
「分かってる。どんな調味料でも渡せるシステムを開発してるんだ。」
「20分も待ってるんだけど。」
「長い目で見たら役に立つから。」

Pythonや機械学習、そして言語の競争について – 極めて主観的な見地から - POSTD (opens new window)

それに、ここで書かれていることを利用しても、部分的にはいくらか速くできますが、 全体としてはそんなに速くなりません。Python はもともと遅い言語です。 パフォーマンスよりも可読性を重視して設計されています。

その遅い言語を、可読性を損なってまでして、ちょっと速くしても得られるものは多くはありません。 例えば、メソッドを変数に代入して実行なんてしてたら可読性がひどく損なわれます。 こうなってきたら一体、何のために Python を使っているのか、わからなくなってきます。

Python 3 が登場したばかりの頃は、Python 2 に比べて若干実行速度が遅くなったらしいです。それくらい可読性を優先しています。 リンク先の例では int と long が統合されたことが影響しているかなと思っています。

しかし、以下の違いは Python 3 は 一般に Python 2 より遅くなるという事実からきています。
Python 2 と 3 の速度の違いについてのメモ - Python 2.7.x と 3.x の決定的な違いを例とともに - POSTD (opens new window)

同じプログラムを別の C 言語などに書き換えれば何倍も早くなります。 Python の高速化と書いてあっても、他のサイトや書籍 "ハイパフォーマンス Python" では、 外部ライブラリや別言語への書き換えを書いてるのは、そのためだと思います。 最初は、なんで Python の高速化なのに C 言語とか Fortran とか別言語の話をしてるんだろう?と疑問に思っていましたが (また髪の話してる... みたいな感じで)

CPython より PyPy の方が速いと言われています。

PyPyはJITを有していますし、前項で述べたように、CPythonに比べて非常に高速です。 このパフォーマンスベンチマークの詳細については以下をご参照ください。 では、どうしてCPythonはJITを使用しないのでしょう JITに対するマイナス面が存在します。そのうちの1つが起動時間です。 CPythonの起動時間は、すでに比較的遅いのですが、PyPyを起動するにはCPythonよりもさらに2~3倍の時間がかかります。
なぜ Python はこんなにも遅いのか? - POSTD (opens new window)

CPython と PyPy の実行速度の比較は、こちらにありました。

この計測結果だと PyPy は Java に匹敵している...

ただ、本当にそうなのかは、確証が得られていません...

以下の記事は Flask の作者 Armin Ronacher によって書かれました。 Armin Ronacher が CPython の実装が好きではないそうです。 何故かというと、細かい最適化がたくさん施されているからだそうです。

Python ではインタープリタの起動は非常に重たい処理です。 Python の実行ファイルを起動すると、なんでも実行してくれる大きな装置が呼び出されます。 この大きな装置は、組込型を起動して、import 機構をセットアップして、必要なモジュールを import して、 OS と協調してシグナルを処理しコマンドライン引数を受け取って、内部状態をセットアップしたりします、 この他にも色々と実行しています。 それが最終的に終わると、 Python のインタープリタは、あなたのコードを走らせて、シャットダウンします。 これは Python は今日に至る 25 年間もの間やっていたことです。
私が見たい Python - The Python I would like to see

PyPy の方が CPython より速いのになぜ使われていないのでしょうか。 PyPy は起動が遅いらしいです。

JITに対するマイナス面が存在します。そのうちの1つが起動時間です。CPythonの起動時間は、すでに比較的遅いのですが、PyPyを起動するにはCPythonよりもさらに2~3倍の時間がかかります。
なぜPythonはこんなにも遅いのか? (opens new window)

そうなると常時、起動したままのサーバサイドのプログラムなら PyPy 使っても良いのでしょうか。 あまりよくわかっていません。

JITの恩恵を受けたくて、それに見合うワークロードがあるなら、PyPyを使いましょう。
なぜPythonはこんなにも遅いのか? (opens new window)

They benchmarked extensively and found that PyPy was only 3 times slower than Go, and considering the insanely fast development time in Python, opted to go with PyPy instead.
Can Python be faster than Go if we use PyPy? (opens new window)

# 2つ目の理由

2つ目は Python は、適切に抽象化具合をあげて短く簡潔に書くことを前提にしていると思われるからです。 このことは、Python がそういった機能を提供しているし、 PEP 8 - Style Guide for Python Code でも 1 行最大 79 文字とごく短く制限されていることから推測しています。

低レベルに書き込むことは、PEP 20 - The Zen of Python の言う、 たったひとつだけあるはずのストレートなやり方ではないと思われるからです。

何かをやるには、ストレートなやり方がひとつ、 たったひとつだけあるはず
There should be one-- and preferably only one --obvious way to do it.
Python にまつわるアイデア: PEP 20 | Life with Python (opens new window)

# まとめ

そんなこんなで、ひとカテゴリ使ってかなり長く書き込んでしまいましたが。 基本的にあまり気にしなくて大丈夫です。 あ、でも list.insert(0, obj) が遅いのだけ覚えおいた方がいいかなと思います。 あれはなかなかの落とし穴なので笑 もし、こんなに長い文章を読んでくれた方がいたら幸いでございます。 誠にありがとうございました!