C# でポインターを使用すると、マネージド コードのみを使用する場合と比較して、パフォーマンスが大幅に向上しますか? c# でのポインターの最適な使用例は何ですか? 具体的な例を念頭に置いているわけではなく、これまでそれらを使用する必要はありませんでした。ポインターを使用するとデータをより高速に操作できるように思えますが、最終的にはすべて簡単なことかもしれません。私がそれらについて考えている唯一の理由は、Matrix クラスの作成に取り組んでおり (学習目的のみ)、すべての計算をできるだけ効率的にしようとしているためです。
6 に答える
C# でポインターを使用すると、マネージド コードのみを使用する場合と比較して、パフォーマンスが大幅に向上しますか?
時々。
c# でのポインターの最適な使用例は何ですか?
非常にパフォーマンスに敏感なコード、および既存のアンマネージ コードとの相互運用性。
具体的な例を念頭に置いているわけではなく、これまでそれらを使用する必要はありませんでした。
私は約 10 年間 C# コードを書いてきましたが、実際の "基幹業務" コードでポインターを使用する必要があったことを思い出したことはありません。テストケース、確かに。しかし、生産用ではありません。
すべての計算をできるだけ効率的にするようにしたいと思います。
StackOverflow でよく耳にします。いいえ、あなたは実際にそれを望んでいません。特定の予算を考慮して、それらを可能な限り効率的にしたいと考えています。たとえば、新しい数学チップの製造に何十億ドルも投資するつもりはないでしょう。 喜んでそうする人もいますが、あなたはその一人ではありません。一部の人々は、そのようなお金を使うことができ、テクノロジーがあれば利益を上げて解決できる問題を抱えています。既存のテクノロジの特定のセットと、それに費やす意思のある時間と労力が与えられた場合、おそらく可能な限り効率的にすることをいとわないでしょう。あなたの目的は実際には速い数学を書くことではなく、プログラムを最適化する方法を学ぶことです。
その場合、プログラムを最適化する方法を学びます。プログラムを最適化する方法は、プロファイリング ツールを使用してコードの問題点を特定し、データに基づいて、安全でないコード ソリューションのコストと利点を調査するかどうかを決定することです。たとえば、コストのほとんどがキャッシュ ミスによるものであり、本当に必要なのは配列範囲チェックを減らすことではなく、より良い局所性である可能性があります。または、問題領域では、メモ化の方が優れた手法であることに気付くかもしれません。プログラムを高速化する方法はたくさんありますが、データがなければ改善されているかどうかはわかりません。
この質問に対する決定的な答えはありませんがunsafe
、固定された構造体 (「ポインター」と呼ばれるもの) を含むコードを使用すると、たとえば、非常にタイトなループで配列をループ処理していて、可能な限り最高速度が必要な場合に、パフォーマンスが向上する可能性がありますが、境界チェックは必要ありません。走行距離は、ループで何をしているかによって異なりますが、 method を宣言するだけで 10% の速度向上が見られましたunsafe
。
アンマネージ コードを使用すると、常に実行が高速になります。マネージ コードを使用すると、常に市場投入が早くなります。アプリケーションを十分に高速化し、後でハードウェアの改善に頼るのに必要なアンマネージ コードの量の決定は、エンジニアリングのトレードオフです。
標準的なアプローチは、主に「市場投入までの時間短縮」を目指し、重要な既知の問題領域を事後に調整することです。これには大きな利点があります。
- クリーンなマネージ コードを作成することで得られる時間は「手元に」あり、既知の問題に対処するために必要に応じて効率的に再焦点を当てることができます。
- 不必要な高度に調整されたコードの作成に費やした時間を取り戻すよりも、クリーンなマネージ コードを書き直してパフォーマンスを向上させる方が簡単です。
ここでの明らかな帰結は、より多くのマネージ コードを記述する方が、その逆よりも安全であるということです。
アンマネージドになると、ほとんどすべてが高速になります。どれだけ速くなるかは、多くの要因に依存します。最も重要な部分を選び、いくつかのテストを行います。
unsafe ブロック内のコードの記述方法に完全に依存します。アンマネージ コードのパフォーマンス上限ははるかに高くなりますが、正しく記述しないと、C# が既定で提供するものよりもパフォーマンスが大幅に低下する可能性があります。たとえば、ポインターを使用して配列内の要素へのより効率的なアクセスを実現している場合、パフォーマンスの向上は大きくなります。それらをオブジェクトへの参照として使用しているだけの場合、通常はそれを割り当ててObj myObj = new Obj()
、おそらく違いはありません。