Pythonで記述されたコードを高速化するために使用できるツールまたはアプローチは何ですか?


29

背景: Krylov部分空間法を使用して行列指数ベクトル積を計算するコードをMATLABからPythonに移植したいと思うかもしれません。(具体的には、この論文で説明されているアルゴリズムを使用するJitse Niesenexpmvp関数。)ただし、コンパイル済みライブラリから派生したモジュールの関数を頻繁に使用しない限り(つまり、多くの組み込みのPython関数で)、それは非常に遅い可能性があります。

質問:パフォーマンスのためにPythonで記述したコードを高速化するのに役立つツールまたはアプローチはありますか?特に、プロセスを可能な限り自動化するツールに興味がありますが、一般的なアプローチも歓迎します。

注: Jitseのアルゴリズムの古いバージョンを使用していますが、しばらく使用していません。このコードを高速にするのは非常に簡単かもしれませんが、良い具体的な例になりそうで、自分の研究に関連しています。この特定のアルゴリズムをPythonで実装するための私のアプローチについては、まったく別の質問です。


この質問に対してPython 固有の回答をしました:scicomp.stackexchange.com/questions/2429/…そこにあるヒントとリンクはあなたに役立つと思います。
AlexE

(これを私に気づかせてくれた@AlexEへのh / t)この質問には間違いなく重複があります。(どのように)より速く実行するシミュレーションを書くのですか?、およびコードのシリアルパフォーマンスを改善するための優れた戦略は何ですか?。何らかの並べ替えが適切に行われる可能性があります。私はそれについてMetaに投稿しました。
ジェフオックスベリー

1
ここでの良い答えに加えて、このリンクをご覧ください
マイクダンラベイ

回答:


40

答えを3つの部分に分けます。プロファイリング、cを介したpythonコードの高速化、およびpythonを介したpythonの高速化。Pythonには、コードのパフォーマンスが実際のボトルネックにドリルダウンしているものを調べるための最良のツールがいくつかあるというのが私の見解です。プロファイルなしでコードを高速化することは、ウジで鹿を殺そうとするようなものです。

mat-vec製品にのみ興味がある場合は、scipy.sparseをお勧めします

プロファイリング用のPythonツール

profileおよびcProfileモジュール:これらのモジュールは、標準のランタイム分析と関数呼び出しスタックを提供します。統計を保存してpstatsモジュールを使用すると、さまざまな方法でデータを表示できます。

kernprof:このツールは、行ごとのコードタイミングなどの処理を行うための多くのルーチンをまとめます

memory_profiler:このツールは、コードの行ごとのメモリフットプリントを生成します。

IPythonタイマーtimeit関数は、関数の違いをすばやくインタラクティブに確認するのに非常に便利です。

Pythonの高速化

Cython:cythonは、Pythonでいくつかの関数を取得し、より高速なコードを取得する最も簡単な方法です。Pythonのcythonバリアントを使用して関数を修飾すると、cコードが生成されます。これは非常に保守的であり、c / c ++ / fortranの他の手書きコードにも簡単にリンクできます。今日では、はるかに好ましいツールです。

ctypes:ctypesを使用すると、cで関数を記述し、コードを簡単に装飾してすぐにラップできます。PyObjectsからキャストし、c関数を呼び出すためにgilを管理するすべての痛みを処理します。

Cでコードを記述するためのその他のアプローチもありますが、C / C ++ライブラリを使用してPythonでラップするためのアプローチはいずれもいくらか優れています。

Pythonのみのアプローチ

主にPythonの内部に滞在したい場合、私のアドバイスは、使用しているデータを把握し、アルゴリズムを実装するための正しいデータ型を選択することです。私の経験では、通常、データ構造を最適化してから低レベルのハックを行うことで、さらに遠くまで到達することができます。例えば:

numpy:配列のストライド操作に非常に高速なコンティンゴス配列

numexpr:numpy配列式オプティマイザー。それはnumpy配列式のマルチスレッド化を可能にし、Pythonインタープリターの制限のためにnumpyが作成する多数の一時的なものも取り除きます。

blist:リストのbツリー実装。リストの内部ノードの挿入、インデックス付け、移動が非常に高速です。

パンダ:データフレーム(またはテーブル)の配列の非常に高速な分析。

pytables:高速構造化された階層テーブル(hdf5など)、特にコアデータの計算や大きなデータへのクエリに適しています。


3
ctypesを使用して、Fortranルーチンを呼び出すこともできます。
マシューエメット


コードのラッピングについて話していますが、f2pyについてはどうですか?
アストロフアンル

f2pyは素晴らしいツールであり、コミュニティの多くの人が使用しています。fwrapは、f2pyがその年齢を示しているが、実際には完全ではないため、より最近の代替品です。
aterrel

ありがとう!これらは私が探していた種類のリソースです。私はそれらのうちのいくつかだけを知っていて、通過したとき(またはインターネット上でそれらを見たとき)にのみでした。Aronはnumexprについて言及し続けています。それはどのように機能しますか?それは当てはまりますか?
ジェフオックスベリー

7

まず、CまたはFortranの実装が利用可能な場合(MATLAB MEX関数?)、Pythonラッパーを作成しませんか?

ラッパーだけでなく独自の実装が必要な場合は、線形代数にnumpyモジュールを使用することを強くお勧めします。最適化されたBLAS(ATLAS、GOTOblas、uBLAS、Intel MKLなど)にリンクされていることを確認してください。そして、Cythonまたは織りを使用します。良い紹介とベンチマークについては、このPerformance Pythonの記事をお読みください。この記事のさまざまな実装は、Travis Oliphant(Numpy-Guru)の好意により、ここからダウンロードできます

がんばろう。


Performance Pythonの記事は少し古くなっているように見えますが、numexprのような新しいツールのいくつかについては言及していません。
アロンアーマディア

numexprを見落としていました。... numexprと同じラプラスベンチマークを実行するためにいいだろう
GertVdE

されてscipy.weaveまだ使用して開発されましたか?Performance Pythonの記事は、高速で使用できることを示しており、速度がかなり改善されているように見えますが、その記事以外で言及されたことはめったにありません。
ケン

@Ken:scipy.weaveは、私の知る限り、現在活発に開発されていません。後方互換性のために保持されていますが、新しいプロジェクトではCythonを使用することをお勧めします。
GertVdE

GotoBLASおよびNumPy / SciPyについては、der-schnorz.de
linear

4

基本的に私は他の答えに同意します。スピーディな数値pythonコードの最適なオプションは次のとおりです。

  • のような特殊なライブラリを使用する numpy
  • python-programが直接呼び出すことができるように、既存のコードをラップします

しかし、アルゴリズム全体をゼロからプログラムしたい場合(引用:「生のPythonのみを使用」)、http://pypy.org/のJIT(Just In Time)実装を検討することをお勧めしますpython。私はプロジェクトにそれを使用することができませんでした(それは依存しnumpyていて、pypy彼らはそれをサポートすることに現在取り組んでいるからです)が、ベンチマークは非常に印象的です(http://speed.pypy.org/


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.