# 禁則事項
意識してコーディング
しないでください
ここで書かれていることを気にして、コーディングしない方が望ましいです。 ここで書かれていることは Python を高速化するための tips というよりも Python の動作とか性質が、 だいたいどんなものかを理解するためのものと捉えていただけると嬉しいです。
もし処理速度を本当に向上させたい場合は、 いくつかやり方があるように感じます。
- cProfile などを使い遅い場所を特定する。
- より良いアルゴリズム、データ構造を検討、採用する。
- Numba など外部ライブラリの利用する。
- 処理を並列化する。
- PyPy を使う。
- Cython を使って CPython を拡張する(C 言語で書き直したりする)
- Go などの全く別言語に書き換える。
特に Python で書くときは、高速化よりも可読性を重視した方が望ましいと感じます。理由は2つあります。
# 1つ目の理由
1つ目は Python は、コードをささっと書き上げることを目的にしているからです。 実行時間を速くすることを目的にしていません。パフォーマンスよりも可読性を優先した例としては、 型にとらわれず自由にプログラミングできるように静的型付けではなく動的型付けを採用したこと、 自由にオブジェクトの属性を追加できるようにしたため属性参照のコストが重くなっていること。
私にとって重要なのは、どうすれば生産性の高い仕事ができるかなのです。 ”生産性”とは何か。私の場合、分析は1回しか行いません(異なるアイデアのテストやデバッギングは別です)。 ある特定のコードを24時間実行することもありません。私はエンドユーザのためのソフトウェアアプリを開発していません。
私は”生産性”を定量化する際、(1)アイデアをコードで書き出す時にかかった時間、(2)デバッギングにかかった時間、 (3)実行にかかった時間の合計時間を想定します。 私にとって”高い生産性”は”結果を出すまでにかかった時間”を意味します。長年の経験から、自分にはPythonが合っていることが分かりました。
「塩を取って」
「だからさ……」
「分かってる。どんな調味料でも渡せるシステムを開発してるんだ。」
「20分も待ってるんだけど。」
「長い目で見たら役に立つから。」
それに、ここで書かれていることを利用しても、部分的にはいくらか速くできますが、 全体としてはそんなに速くなりません。Python はもともと遅い言語です。 パフォーマンスよりも可読性を重視して設計されています。
その遅い言語を、可読性を損なってまでして、ちょっと速くしても得られるものは多くはありません。 例えば、メソッドを変数に代入して実行なんてしてたら可読性がひどく損なわれます。 こうなってきたら一体、何のために Python を使っているのか、わからなくなってきます。
Python 3 が登場したばかりの頃は、Python 2 に比べて若干実行速度が遅くなったらしいです。それくらい可読性を優先しています。 リンク先の例では int と long が統合されたことが影響しているかなと思っています。
しかし、以下の違いは Python 3 は 一般に Python 2 より遅くなるという事実からきています。
Python 2 と 3 の速度の違いについてのメモ - Python 2.7.x と 3.x の決定的な違いを例とともに - POSTD
同じプログラムを別の C 言語などに書き換えれば何倍も早くなります。 Python の高速化と書いてあっても、他のサイトや書籍 "ハイパフォーマンス Python" では、 外部ライブラリや別言語への書き換えを書いてるのは、そのためだと思います。 最初は、なんで Python の高速化なのに C 言語とか Fortran とか別言語の話をしてるんだろう?と疑問に思っていましたが (また髪の話してる... みたいな感じで)。
CPython より PyPy の方が速いと言われていますが PyPy は起動が遅いらしいです。 そうなると常時、起動したままのサーバサイドのプログラムなら PyPy 使った方がいいのでしょうか。 あまりよくわかっていません。
PyPyはJITを有していますし、前項で述べたように、CPythonに比べて非常に高速です。 このパフォーマンスベンチマークの詳細については以下をご参照ください。 では、どうしてCPythonはJITを使用しないのでしょう JITに対するマイナス面が存在します。そのうちの1つが起動時間です。 CPythonの起動時間は、すでに比較的遅いのですが、PyPyを起動するにはCPythonよりもさらに2~3倍の時間がかかります。
なぜ Python はこんなにも遅いのか? - POSTD
PyPy3で出すと通りますよ~!
— あっと (@AT274_) May 11, 2019
この計測結果だと PyPy は Java に匹敵している...
ただ、本当にそうなのかは、確証が得られていません...
JIT効いてないのかな?
— 齊藤健司(ゆめかけ) (@yume_piece1010) July 28, 2019
PyPyもそれなりに速いみたいだけど、Javaってここまでパフォーマンス出ないことないような… https://t.co/oxSSNjF8lD
以下の記事は Flask の作者 Armin Ronacher によって書かれました。 Armin Ronacher が CPython の実装が好きではないそうです。 何故かというと、細かい最適化がたくさん施されているからだそうです。
Python ではインタープリタの起動は非常に重たい処理です。 Python の実行ファイルを起動すると、なんでも実行してくれる大きな装置が呼び出されます。 この大きな装置は、組込型を起動して、import 機構をセットアップして、必要なモジュールを import して、 OS と協調してシグナルを処理しコマンドライン引数を受け取って、内部状態をセットアップしたりします、 この他にも色々と実行しています。 それが最終的に終わると、 Python のインタープリタは、あなたのコードを走らせて、シャットダウンします。 これは Python は今日に至る 25 年間もの間やっていたことです。
私が見たい Python - The Python I would like to see
# 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
高速化のためにC++を使うべきかは、 サーバ代(ネットワークを除く)と人件費のどちらが高いかなだけで、大抵の会社は人件費の方が高いので(Goにすることさえ)高速化自体には価値がなく開発効率こそが重要なだけかと思う。開発者数に対するユーザ数が多いGoogleとかだとC++の効果は絶大。 https://t.co/pEs4XjxNG4
— いもす (@imos) October 25, 2017
一番需要あるのはDB設計とクエリ高速化で、ついでキャッシュ設計なので、 バイナリに近いレベルの高速化にたどり着くプレーヤーが国内にほぼない...
— human eslint --fix (@mizchi) July 11, 2018
# まとめ
そんなこんなで、ひとカテゴリ使ってかなり長く書き込んでしまいましたが。 基本的にあまり気にしなくて大丈夫です。 あ、でも list.insert(0, obj) が遅いのだけ覚えおいた方がいいかなと思います。 あれはなかなかの落とし穴なので笑 もし、こんなに長い文章を読んでくれた方がいたら幸いでございます。 誠にありがとうございました!