0

私たちの描画コードのこの奇妙な小さな最適化で何が起こっているのか、誰か説明してもらえないだろうか。コードの最初の小さなビットを 2 番目のコードに置き換え、速度が大幅に向上しました (ストップウォッチ クラスを使用して 4400 ティック -> 15 ティック)。

// Add all the visible sprites to the list
m_renderOrder.Clear();
foreach (CSpriteInternalData sprite in m_InternalData)
{
    if (!sprite.m_bRender) continue;
    m_renderOrder.Add(sprite);
}

交換された...

// Add all the visible sprites to the list
m_renderOrder.Clear();
renderOrderCount = 0;
for (int i = 0; i < m_numSprites; i++ )
{
    if (m_InternalData[i].m_bRender)
        m_renderOrder[renderOrderCount++] = m_InternalData[i];
}

速度が大幅に向上したため、私は最も単純な小さな変更のように見えます。誰でも助けることができますか?

4

3 に答える 3

3

CSpriteInternalDataが、つまり値型の場合struct、その型の値を変数に代入するたびに、コピーが行われます。

MyStruct a = new MyStruct(50);
MyStruct b = a; //a is copied to b;
a.Value = 10;
Console.WriteLine(b.Value); //still 10, has a separate copy of value

構造体が小さくて移植可能であれば、それほど問題にはなりませんが、構造体が大きいと遅くなる可能性があります。Foreachは、コレクションから値が繰り返し割り当てられる変数を作成します。したがって、CSpriteInternalDataが の場合struct、それぞれが順番にsprite変数にコピーされます。これには時間がかかる可能性があります。

また、Addアイテムをコレクションに入れるときの行は、構造の別のコピーを呼び出しますが、フラグが設定されm_renderOrderているのはそのうちのいくつかだけだと思います。m_bRender

CSpriteInternalDataそれがスローダウン/スピードアップの原因である場合は、参照動作を使用するクラスに変更し、全体のコピーではなく参照をコピーすることを心からお勧めします。

于 2012-10-05T08:49:00.733 に答える
0

foreach ループの目的は少し異なります。これは、IEnumerable を実装するコレクションを繰り返し処理するためのものです。そのパフォーマンスははるかに遅くなります。

あなたが見ることができる参照のために

http://www.codeproject.com/Articles/6759/FOREACH-Vs-FOR-C

于 2012-10-05T08:54:35.707 に答える
0

foreach は常に、GetEnumerator メソッドによって返される列挙子のインスタンスを作成し、その列挙子も foreach ループのライフ サイクルを通じて状態を保持します。次に、列挙子で Next() オブジェクトを繰り返し呼び出し、返される各オブジェクトに対してコードを実行します。

場合によっては、独自のエミュレーターを作成できます。ただし、実行時間が重要な場合は、代わりに for ループを使用することをお勧めします。

于 2012-10-05T08:45:55.660 に答える