私は、画像処理技術を使用して信号分析を行う定量的ライブラリのプロトタイプを作成しています。最初のプロトタイプはすべてC#で作成しましたが、パフォーマンスは期待したほど良くありません。ほとんどの計算は重い行列計算によって行われ、これらはほとんどの時間を占めています。
アンマネージC++コードへのC++/CLIインターフェイスを作成する価値があるかどうか疑問に思っています。誰かがこれを経験したことがありますか?C#のパフォーマンスを最適化するための他の提案を歓迎します。
私は、画像処理技術を使用して信号分析を行う定量的ライブラリのプロトタイプを作成しています。最初のプロトタイプはすべてC#で作成しましたが、パフォーマンスは期待したほど良くありません。ほとんどの計算は重い行列計算によって行われ、これらはほとんどの時間を占めています。
アンマネージC++コードへのC++/CLIインターフェイスを作成する価値があるかどうか疑問に思っています。誰かがこれを経験したことがありますか?C#のパフォーマンスを最適化するための他の提案を歓迎します。
C / C ++で書く方が間違いなく良い時期がありましたが、C#オプティマイザーとJITは非常に優れているため、純粋数学ではおそらく違いはありません。
違いは、メモリと場合によっては配列を処理する必要がある場合に発生します。それでも、C#(またはF#)を使用して、ホットスポットを最適化します。JITは、小さくて寿命の短いオブジェクトを最適化するのに非常に優れています。
配列の場合、C#が各アクセスで境界チェックを実行することを心配する必要があります。これを読む:
自分でテストしてください-私はC#が同等であることがわかりました-時にはより速くなります。
ここで明確な答えを出すのは難しいですが、パフォーマンスが問題である場合は、必要なパフォーマンスを備えた実績のあるライブラリを見つけて、それをラップします。
乗算や除算のような単純なものは、c ++とc#の間でそれほど違いはありません。c++コンパイラにはオプティマイザがあり、CLRランタイムには最適化を行うオンデマンドJITerがあります。したがって、理論的には、c ++は最初の呼び出しでのみc#よりもパフォーマンスが高くなります。
しかし、理論と実践は同じではありません。より複雑なアルゴリズムを使用すると、メモリマネージャー間の違いや、最適化手法の成熟度にも遭遇します。事例証拠が必要な場合は、ここで数学を多用する比較を見つけることができます。
個人的には、ネイティブライブラリで大量の計算を実行し、c ++ / CLIを使用してそれを呼び出すと、計算が最大のボトルネックになる場合に大きな効果が得られます。いつものように、最適化を行う前に、それが事実であることを確認してください。
私の意見では、行列の計算はネイティブコードで行うのが最適です。C ++ライブラリでさえ、通常、 LAPACKのような低レベルの実装へのバインドを許可します。
ここにC#LAPACKポート(同じサイトのC#BLASもあります)がありますが、これがネイティブコードよりも高速である場合は驚きます。
私はC#で多くの画像処理作業を行ってきました。もちろん、パフォーマンスが重要なヘビーデューティーコードにはネイティブコードを使用しますが、C ++/CLIインターフェイスではなくPInvokesのみを使用しました。ただし、多くの場合、これは必要ありません。
かなりの数の優れた.NETプロファイラーがあります。レッドゲートは私の個人的なお気に入りです。ボトルネックがどこにあるかを視覚化するのに役立つ場合があります。
そこにある唯一の合理的な言語ベンチマーク:http ://shootout.alioth.debian.org/
自分で見て。
計算量の多いプログラムはC++で作成する必要があります。C#を最適化しても、C++のパフォーマンスに近いところに到達することはできません。計算にかなりの時間がかかると仮定すると、ラッパーを呼び出すオーバーヘッドはごくわずかです。私はC++とC#の両方でコーディングを行ってきましたが、.NETFrameworkコードがC++に匹敵するような機会は見たことがありません。C#がより適切に実行される場合がいくつかありますが、適切なライブラリがないか、C ++でのコーディングが不適切なため、より適切でした。C#とC ++で同じようにコードを記述できる場合は、パフォーマンスコードをC ++で記述し、それ以外はすべてC#です。
xが世界最高のC++プログラマーであり、yが最高のC#プログラマーである場合、ほとんどの場合、xはyよりも高速なコードを記述できます。ただし、ほとんどの場合、yはxよりも速くコーディングを完了することができます。
数学計算のパフォーマンスは、C#ではかなり劣っています。私は、C#での数学計算がどれほど遅いかを知りました。いくつかの乗算、Sin、Cosなどを含むC#とC ++でループを作成するだけで、違いは計り知れません。
私はマネージC++を知りませんが、すべてをアンマネージC ++ abdに実装すると、P/Invokeを介して詳細なインターフェイスを公開してもパフォーマンスにほとんど影響がないはずです。
それは私が重いリアルタイム画像処理のためにしたことです。
最初のプロトタイプはすべてC#で作成しましたが、パフォーマンスは期待したほど良くありません。
次に、2つのオプションがあります。
C ++で別のプロトタイプを作成し、それがどのように比較されるかを確認するか、C#コードを最適化します。どの言語で記述しても、プロファイリングと最適化、およびプロファイリングと最適化が完了するまで、コードは高速になりません。これは特にC++に当てはまります。C#で可能な限り最速の実装を記述し、それをC ++で可能な限り最速の実装と比較すると、C++バージョンの方がおそらく高速になります。ただし、開発時間の面でコストがかかります。効率的なC++コードを書くのは簡単ではありません。この言語を初めて使用する場合、特にC#またはJavaを使用している場合は、非常に非効率的なコードを作成する可能性が高くなります。C#またはJavaでは、処理方法やコストが異なります。
パフォーマンスをあまり気にせずに、機能する実装を作成するだけであれば、C#バージョンの方がおそらく高速になると思います。
ただし、実際には、実行するパフォーマンスの種類(特に、実行する必要のある操作のコスト)によって異なります。マネージドコードからネイティブコードへの移行にはオーバーヘッドが伴うため、短い操作には価値がありません。頻繁に実行されます。
C ++での数値計算コードは、Fortranで記述されたコードと同じくらい高速です(数パーセントを与えるか、または取る)が、それを実現するには、多くの高度な手法(式テンプレートと多くのメタプログラミング)またはかなり複雑なものを使用する必要がありますあなたのためにそれを実装するライブラリ。
それだけの価値はありますか?または、C#をニーズに合わせて十分に高速化できますか?