2017-09-23 18 views
-1

私はパーティクルモデルを作成中です。このシミュレーションには、種のインデックス(パーティクルタイプを識別する)、3D空間内の位置/速度などの属性を持つ多数のパーティクルを作成することが含まれます。また、シミュレーション実行中に計算される空間内の位置に基づいてプロパティを設定します。私はこれまで、巨大な配列を使ってこのモデルを実行していました。ここでは、各行は単一のパーティクルに対応し、各列はパーティクル属性に対応しています。Pythonクラスのパフォーマンスへの影響:Scientific Computing

私の主な質問は次のとおりです。各パーティクルを表すインスタンスを生成できるように「パーティクル」クラスを作成すると、計算速度に関してパフォーマンスが低下しますか?もし100万個の粒子を持つプログラムを走らせたいのであれば、すべての数値を1つの大きな配列に入れておくのが効率的か(それはかなり読みにくいですが)、あるいはこのクラスのインスタンスを使うのと同じくらい効率的ですシミュレーションが進行するとインスタンスの属性?それとも、クラスは問題ないのですか?Pythonリスト/ NumPy配列に多くのクラスインスタンスを格納すると、実際には実行が遅くなりますか?

このプログラムは、数値計算(特にjitclass http://numba.pydata.org/numba-doc/latest/user/jitclass.html#numba.jitclassのようなものを介して)のために最適化されたPythonモジュール "Numba"と共に使用されます。しかし、私はこのモジュールのパフォーマンス上の利点を破壊することは望ましくありません。私のシミュレーションで変数を宣言して非効率的に実行させることです。

ありがとうございます!

+0

あなたは構造体までのクラスを最適化することができれば、本当にjitclassesを使用してパフォーマンスの低下がありません。つまり、私の分野のほとんどの仕事は、伝統的にC++の拡張機能を書いてから、SWIGやBoost :: Pythonのようなラッパーを使ってPythonでラップします。最終的に、簡単なテストケースとプロファイル、プロファイル、プロファイルを記述します。 –

+0

'numba'が何をすることができるのか分かりませんが、通常dtypeオブジェクトの配列は数値の配列よりはるかに遅いです。リストのように、これらの配列の値は実際にはメモリ内の他の場所のオブジェクトへのポインタです。私の最近の答えはhttps:// stackoverflowを見てください。com/questions/46350208/numpy-arrays-vs-lists-for-custom-classesにあります。 – hpaulj

+0

Particlesクラスを作成する動機は何ですか?その場合は、パーティクルの情報を取得/変更するメソッドを使用して、パーティクルの母集団を表すクラスを作成することができます。これにより、パーティクルを処理するためのより高いレベルの抽象を作成することができますが、メモリ内にデータを散らばらないように、基礎となるパーティクルデータを配列に格納することもできます。 – charlesreid1

答えて

2

は、私が以前に

は良いアイデアのような音巨人numpyの配列を使用して、このモデルを実行してきました。

各パーティクルを表すインスタンスを生成できるように「パーティクル」クラスを作成すると、計算速度に関してパフォーマンスが低下しますか?

おそらくはるかに遅くなります。

numpyのアレイを使用して、既存のソリューションを使用すると、1つの大きなアレイ内のすべてのあなたの粒子を表すことができます:あなたは、粒子ごとにクラスのインスタンスを使用するように変更した場合

id species x y z dx dy dz 
id species x y z dx dy dz 
id species x y z dx dy dz 

、あなたはまだ(numpyの配列でそれらを保つことができますまたはリスト)が表示されますが、次のようになります。

object -> [id species x y z dx dy dz] 
object -> [id species x y z dx dy dz] 
object -> [id species x y z dx dy dz] 

これは、1(配列)の代わりに割り当てる必要がある4つのN + 1オブジェクトです。

大きな問題を引き起こしていない限り、私はオリジナルのデザインである巨大なNumPyアレイに固執します。

+0

正直なところ、Cython/Swig/Boostを使ってC++にダイビングするのに最善の答えはないでしょう。 JitClassesは高速かもしれませんが、NumPyではオブジェクトとして扱われているとは思われません。これはポインタとそのための連続しないストレージ、アクセスが遅く、オーバーヘッドが増えることを意味します。 C++の拡張はこれらの問題の多くを解決し、実装するのは簡単ですが、そのような単純な例では努力する価値はありません(パッケージの問題は言及しません)。 –

0

あなたがここに構造化されたデータ型を使用する必要があります。

particle_dtype = np.dtype([ 
    ('id', int), 
    ('species', (np.unicode_, 16)), 
    ('pos', np.float32, 3), 
    ('vel', np.float32, 3) 
]) 

particles = np.empty(100, dtype=particle_dtype) 
particles[0]['id'] = 1 
particles['pos'] += particles['vel'] * dt 
関連する問題