10

私はC++科学アプリケーションをPythonに移植していますが、Pythonを初めて使用するため、いくつかの問題が頭に浮かびます。

1)座標(x、y)を含むクラスを定義しています。これらの値は数回アクセスされますが、クラスのインスタンス化後にのみ読み取られます。メモリとアクセス時間の両方でタプルまたはnumpy配列を使用する方が良いですか?

2)場合によっては、これらの座標を使用して複素数を作成し、複素関数で評価し、この関数の実数部を使用します。この関数の実数部と複素数部を分離する方法がなく、実数部を最後に使用する必要があると仮定すると、(x、y)を格納するために直接複素数を使用する方が良いでしょうか?Pythonで複雑なものから実際のものに変換する際のオーバーヘッドはどれほど悪いですか?C ++のコードはこれらの変換の多くを実行しますが、これはそのコードの大きな速度低下です。

3)また、いくつかの座標変換を実行する必要があります。座標については、x値とy値に別々にアクセスし、変換を実行して、結果を返します。座標変換は複素平面で定義されているので、複素変数に依存するよりも、コンポーネントxとyを直接使用する方が高速ですか?

ありがとうございました

4

2 に答える 2

7

メモリ消費の点では、numpy配列はPythonタプルよりもコンパクトです。numpy配列は、単一の連続したメモリブロックを使用します。numpy配列のすべての要素は、宣言された型(32ビットまたは64ビットのfloatなど)である必要があります。Pythonタプルは必ずしも連続したメモリブロックを使用する必要はなく、タプルの要素は任意のPythonオブジェクトにすることができます。一般に、numpy数値型よりも多くのメモリを消費します。

したがって、この問題はnumpyにとっては手に負えない勝利です(配列の要素をnumpy数値型として格納できると仮定します)。

速度の問題については、「コードをベクトル化できますか?」という質問に要約すると思います。

つまり、計算を配列全体に対して要素ごとに実行される操作として表現できますか。

コードをベクトル化できる場合、numpyはPythonタプルよりも高速である可能性があります。(私が想像できる唯一のケースは、非常に小さなタプルが多数ある場合です。この場合、numpy配列を形成するオーバーヘッドと、numpyをインポートするための1回限りのコストが、ベクトル化の利点を損なう可能性があります。)

ベクトル化できなかったコードの例は、たとえば、配列内の最初の複素数を調べz、整数インデックスを生成する計算を実行しidx、次に取得z[idx]し、その数に対して計算を実行することで、次のインデックスidx2、次に取得z[idx2]など。このタイプの計算はベクトル化できない場合があります。この場合、numpyの強みを活用できないため、Pythonタプルを使用することをお勧めします。

複素数の実数部/虚数部にアクセスする速度については心配しません。私の推測では、ベクトル化の問題によって、どちらの方法が速いかが決まる可能性が高いと思います。(ただし、numpyは、複素数配列をストライドし、1つおきのfloatをスキップして、結果をfloatとして表示するだけで、複素数の配列を実際の部分に変換できます。さらに、構文は非常に単純ですz。複雑なnumpy配列z.realは、float numpy配列としての実際の部分です。これは、属性ルックアップのリスト内包表記を使用する純粋なPythonアプローチよりもはるかに高速である必要があります[z.real for z in zlist]

好奇心から、C ++コードをPythonに移植する理由は何ですか?

于 2010-04-02T03:37:33.643 に答える
3

余分な次元を持つ配列は、タプルの配列とnumpy同じように、メモリの使用がより厳しく、少なくとも同じくらい高速です。numpy複素数は、3番目の質問を含めて、少なくとも同じかそれ以上です。ところで、あなたは-あなたの質問よりも後で質問がたくさん答えられている間-あなたは休眠していることに気づいたかもしれません:理由の一部は、質問内で3つの質問をすることで応答者がオフになることは間違いありません。質問ごとに1つの質問をしてみませんか?質問などで課金されるわけではありません...!-)

于 2010-04-02T02:50:41.020 に答える