Last Updated: 4/22/2020, 12:43:08 PM

# 最適化したい。

Python のコードは、
頑張って書けば書くほど
遅くなります。
C 言語などの高速な言語で
実装されたライブラリを
使って書きます。

# 結論

今回利用するコードは、こちらにまとめさせていただきました。

$ # 実行例 各スクリプトは、そのまま実行できます。
$ python3 4_3_sieve_of_eratosthenes.py

低レベルな書き方、高レベルな書き方というのは、 主観で書かせていただきました。 分岐は if, try 文, 反復は for, while 文, 順次はそれ以外です。

比較したもの一覧
項番 分類低レベルな書き方 高レベルな書き方
1 順次速 リテラルの参照遅 変数の参照
2 順次速 変数の参照 遅 属性の参照
3 順次速 ベタ書き 遅 関数
4 反復遅 while 文 速 for 文
5 反復遅 for 文 速 リスト内包表記
6 分岐遅 if 文速 try 文

コードの説明は、以下の各記事に記述させていただきました。

ここで取り扱うこと
• Python の構文を使った処理速度の比較
• 最初から入ってる組込モジュール、クラス、関数を使った処理速度の比較

ここで取り扱わないこと
• Numba など外部ライブラリの利用
• 別言語への書き換え(例えば Cython を利用して C 言語に書き換え)

請注意
 ここで取り扱うことを気にして、コーディングしないでください。  ここで取り扱うことは かなり重箱の隅をつつくようなことをしています。 なぜ、このような細かい最適化が重要でないかは、このカテゴリ「最適化」のおわりにで書かせていただきました。

# 概観

低レベルにガリガリ書き込んだ方が速くなりそうな気がします。 しかし Python は、そうではないところがあります。 この主な原因は Python が、遅いからです。

そのため Python のコードを書けば書くほど遅くなります。 大抵の場合、コードが  短い方が速い  です。 すべての場合で当てはまるわけではなく、 あくまでもそんな雰囲気かな程度の話です。

自分で書かないで、「組み込み関数」を使ったり あるいは  C 言語で書かれた  「ライブラリ」を import して書くと言うことです。 最初から提供されている神々が書いてくれた組み込みの関数を使った方が速いということでしょうか。

ライブラリは C 言語で書かれているものもあれば、 Python で書かれているものもあります。 同じ機能を提供しているものがないので、 両者を単純に比較することは本来はできませんが...

itertools などの C で書かれたライブラリは、速い感じがします。

copy などの Python で書かれたライブラリは、遅い感じがします。

ちなみに、同じモジュールであっても Python 側で実装されていたり、 C 側実装されていたりするそうです。

collections.OrderedDict は Python 側で実装された型であるのに対して、 同じモジュールにある collections.defaultdict は C 言語側で実装されている型です。 このことは実際に PyPy で相当数の問題を引き起こしています。これらの違いが目立たない類似の API を実現するため、 できるだけオリジナルの型を模倣する必要があるからです。
Revenge of the Types: 型の復讐

# 背景

ごくたまに真面目に Python のコードを書いていると、 どちらのコードが良い書き方なのか、ふと疑問に思うときがあります。

そんなとき最適化する、すなわち2つの書き方の時間を計測することで、 どちらが良い書き方なのか、なんとなく、わかるときがあります。 完全解は与えてはくれませんが、書き方のなんとなくの指針を与ええてくれます。

具体的に言えば、項番 4, 5, 6 が該当します。 for 文で書くべきか while 文で書くべきか、 あるいは リスト内包表記で書くべきか for 文で書くべきか、 そして try 文で書くべきか if 文で書くべきか、 この辺りですこし引っかかっていました。

ただ、ここで書かれていることを実行しても、あまり速くはなりません。 そのため、こういうものもあるんだな程度に、押さえておいていただければと思います。

全体像だけ、ごくごく、ざっくり眺めていただければと思います。 各ページで、最初に測定対象のコードを列挙するので、どれが速いか選んでいただいて、 あとは結果を見て、「ふーん」と読み流すような感じを想定しています。 この記事は、あくまでも全体像なんとなくの  雰囲気  をお伝えするためのものです。

実際に自分が書いているコードを cProfile などを使って、 計測、遅い場所を特定して最適化する方が、 きっと楽しいと思いますし雰囲気も伝わりやすいかなと思うからです。

以上になります。 ありがとうございました。

Python のコードを最適化したい