2

構造体の配列をクラスの配列およびクラスのリストと比較する多くのテストを実行してきました。これが私が実行してきたテストです:

struct AStruct {
    public int val;
}
class AClass {
    public int val;
}

static void TestCacheCoherence() 
{
    int num = 10000;
    int iterations = 1000;
    int padding = 64;

    List<Object> paddingL = new List<Object>();

    AStruct[] structArray = new AStruct[num];
    AClass[] classArray = new AClass[num];
    List<AClass> classList = new List<AClass>();

    for(int i=0;i<num;i++){
        classArray[i] = new AClass();
        if(padding >0) paddingL.Add(new byte[padding]);
    }
    for (int i = 0; i < num; i++)
    {
        classList.Add(new AClass());
        if (padding > 0) paddingL.Add(new byte[padding]);
    }

    Console.WriteLine("\n");
    stopwatch("StructArray", iterations, () =>
    {
        for (int i = 0; i < num; i++)
        {
            structArray[i].val *= 3;
        }
    });
    stopwatch("ClassArray ", iterations, () =>
    {
        for (int i = 0; i < num; i++)
        {
            classArray[i].val *= 3;
        }
    });
    stopwatch("ClassList  ", iterations, () =>
    {
        for (int i = 0; i < num; i++)
        {
            classList[i].val *= 3;
        }
    });

}

static Stopwatch watch = new Stopwatch();

public static long stopwatch(string msg, int iterations, Action c)
{
    watch.Restart();
    for (int i = 0; i < iterations; i++)
    {
        c();
    }
    watch.Stop();

    Console.WriteLine(msg +":  " + watch.ElapsedTicks);
    return watch.ElapsedTicks;
}

私はこれをリリースモードで次のように実行しています:

 Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(2); // Use only the second core 
 Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
 Thread.CurrentThread.Priority = ThreadPriority.Highest;

結果:

padding=0 を使用すると、次のようになります。

StructArray: 21517
ClassArray:  42637
ClassList:   80679

padding=64 を使用すると、次のようになります。

 StructArray: 21871
 ClassArray:  82139
 ClassList:   105309

padding=128 を使用すると、次のようになります。

 StructArray: 21694
 ClassArray:  76455
 ClassList:   107330

違いがもっと大きいと予想していたので、これらの結果には少し混乱しています。すべての構造体は小さく、メモリ内に次々と配置されますが、クラスは最大 128 バイトのガベージによって分離されます。

これは、キャッシュの使いやすさについても心配する必要がないということですか? それとも私のテストに欠陥がありますか?

4

1 に答える 1

1

ここでは多くのことが起こっています。1 つ目は、テストで GC が考慮されていないことです。リストのループ中に配列が GC されている可能性は明らかです (リストを反復している間は配列が使用されなくなったため、適格です)。コレクション用)。

List<T>2 つ目は、とにかく配列に支えられていることに留意する必要があるということです。唯一の読み取りオーバーヘッドは、 を通過するための追加の関数呼び出しListです。

于 2012-08-28T19:53:47.057 に答える