7

私は XNA で構築しているゲームの C# 最適化について多くの調査を行ってきましたが、ローカル変数がインスタンス変数であるかどうかは、常に更新して使用するとパフォーマンスが向上するかどうかはまだよくわかりません。

http://www.dotnetperls.com/optimizationによると、パラメーターとローカル変数を避ける必要があります。つまり、インスタンス変数がパフォーマンスの点で最良のオプションです。

しかし、少し前に、私は別の StackOverflow の投稿 (どこにあったかを見つけることができないようです) を読んで、ローカル変数はメモリの一部に格納されており、アクセスがはるかに高速であり、インスタンス変数が設定されるたびに、新しい値を割り当てる前に、面倒な追加手順として以前の値を消去する必要があります。

設計上、そのような状況でインスタンス変数を使用するとカプセル化が壊れる可能性があることは知っていますが、パフォーマンスについては非常に興味があります。現在、私のゲームでは、クラス内の 7 つのメソッドのうち 3 つにローカル変数を渡していますが、変数をインスタンス変数に簡単に昇格させ、パラメーターの受け渡しとローカル変数を完全に回避することができました。

では、どちらが良いでしょうか?

4

3 に答える 3

2

個人的には、これをパフォーマンスの問題の原因とは考えていません (常に大きなstructs を渡している場合を除きます)。私の素朴な理解では、GC プレッシャーは XNA ゲームでは通常の考慮事項であるため、基本的にオブジェクト インスタンスを節約する必要があります。

変数がメソッド ローカルの場合、値自体または参照 (参照型の場合) がスタックに配置されます。それらをクラス メンバー変数に昇格させると、それらはヒープ上のクラスのメモリに配置されます。

呼び出しで参照や値をコピーしなくなるため、メソッド呼び出しは技術的に高速になります (メソッドがクラスに対してローカルでもある場合は、メソッドからパラメーターを削除できるため)。

相対的なパフォーマンスについてはわかりませんが、値を永続化する必要がある場合、値はクラスにあることに意味があるようです...

私には、一方を他方に有利にすることから得られる潜在的な利益よりも、両者の微妙な違いが勝っているように思えます。

もちろん、これはすべて、パフォーマンス プロファイリングからの厳しい数値に直面して修正する必要があります。

于 2012-07-27T08:45:04.440 に答える
2

変数は参照 (クラス、または文字列) または値 (構造体) 型ですか?

参照型の場合、それらをメソッド引数として渡すことと、オブジェクト インスタンスに保持することの間に意味のある違いはありません。関数に入る最初のケースでは、引数は (引数の数が少ない関数の場合) レジスタに格納されます。2 番目のケースでは、参照は「this」によってメモリ内でポイントされたデータのオフセットとして存在します。どちらのシナリオも、メモリ アドレスをすばやく取得し、関連するデータをメモリからフェッチすることです (これはコストのかかる部分です)。

値型の場合、上記は特定の型 (CPU のレジスタに収まる整数または浮動小数点数) に当てはまります。これらの特定のものについては、「this」からそれらを抽出するよりも、値渡しの方がおそらく少し安くなります。他の値の型 (DateTime または自分で作成した構造体、または複数のメンバーを持つ構造体) の場合、データが大きすぎてレジスタを通過できないため、これは問題ではなくなります。

ただし、これがアプリケーション (ゲームであっても) のパフォーマンスに影響を与える可能性はほとんどありません。最も一般的な .NET パフォーマンスの問題 (単純に非効率なアルゴリズムではない) は、何らかの形でガベージ生成から発生します。これは、偶発的なボックス化、文字列構築の不適切な使用、またはオブジェクトの有効期間管理の不適切さ (オブジェクトの有効期間が非常に短くも長くも永続的でもない) によって明らかになる可能性があります。

于 2012-07-27T09:17:24.577 に答える
1

引数を渡さないほうがわずかに速くなり、ローカル オブジェクトを初期化しない (オブジェクトの場合) ほうが速くなります。

両方の記事で読んだ内容は矛盾していません。1 つは引数を渡すのに時間がかかること、もう 1 つはオブジェクト (ローカル オブジェクト内) の初期化にも時間がかかる可能性があることを述べています。

新しいオブジェクトの割り当てについて、できることの 1 つは、オブジェクトを破棄するのではなく再利用することです。たとえば、少し前に、C/C++ と C# でいくつかの商品の価格をリアルタイムで計算するトレーダー向けのコードを書かなければなりませんでした。方程式系を最初から作り直すのではなく、以前のシステムから段階的にシステムを更新するだけで、パフォーマンスが大幅に向上しました。

これにより、新しいオブジェクトにメモリを割り当てたり、新しいオブジェクトを初期化したりする必要がなくなり、多くの場合、システムはほぼ同じになるため、更新するためにほんの少し変更するだけで済みます。

通常、最適化を行う前に、全体的なパフォーマンスに大きな影響を与える何かを最適化していることを確認したいですか?

于 2012-07-27T08:46:46.017 に答える