0

私は、Jon Skeet の優れた本C# In Depthを読むのに忙しいです。彼は、ボックス化とボックス化解除に関するセクションで、ボックス化されたオブジェクトを使用すると小さなオーバーヘッドが発生し、十分な規模でパフォーマンスの違いが生じる可能性があると述べています。

そこで、for ループを使用して 1 から 100,000,000 までのすべての数値を加算する独自のベンチマーク テストを作成しました。あるケースではInt32、を使用intしてから にキャストしobject、 にキャストし直しましたint。すべてのテストを 10 回繰り返し、平均を取った。結果 (秒):

Int32 平均: 0.333

内部平均: 0.326

オブジェクト平均: 1.061

と の間に大きな違いはありませんInt32int、ボックス化/ボックス化解除には 3 倍の時間がかかりました!

だから私がここで理解するのを手伝ってください:あなたが を にキャストするとき、それを にキャストするintobjectと同じではありませんInt32か? DotNetPerlsintは、これは実際には単なるエイリアスであると主張していますが、そうである場合、わずかにそうであっても、一貫して よりも高速に実行さInt32れるのはなぜですか?intInt32

編集:一般的なリクエストにより、ベンチマーク コードは次のとおりです。

const int SIZE = 100000000, ITERATIONS=10;
var intTimes = new List<double>();
var int32Times = new List<double>();
var objectTimes = new List<double>();

for (var n = 0; n < ITERATIONS; n++)
{
    Console.WriteLine("Iteration "+(n+1));
    Console.WriteLine("Testing using Int32");
    long result = 0;
    var sw = Stopwatch.StartNew();
    for (Int32 x = 0; x < SIZE; x++)
    {
        result += x;
    }
    sw.Stop();
    int32Times.Add(sw.Elapsed.TotalSeconds);
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds);

    Console.WriteLine("Testing using int");
    result = 0;
    sw = Stopwatch.StartNew();
    for (int x = 0; x < SIZE; x++)
    {
        result += x;
    }
    sw.Stop();
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds);
    intTimes.Add(sw.Elapsed.TotalSeconds);

    Console.WriteLine("Testing using object");
    result = 0;
    sw = Stopwatch.StartNew();
    for (int i = 0; i < SIZE; i++)
    {
        object o = i;
        result += (int) o;
    }
    sw.Stop();
    Console.WriteLine("Result = {0} after {1:0.000} seconds", result, sw.Elapsed.TotalSeconds);
    objectTimes.Add(sw.Elapsed.TotalSeconds);
}
Console.WriteLine("Summary:");
Console.WriteLine("Int32 avg: {0:0.000}", int32Times.Average());
Console.WriteLine("int avg: {0:0.000}", intTimes.Average());
Console.WriteLine("object avg: {0:0.000}", objectTimes.Average());
4

1 に答える 1

3

c# キーワードintは のエイリアスですSystem.Int32。したがって、まったく同じように実行します。

もちろん、マシンは他のタスクも実行しているため、測定中には常に変動があります。

をキャストするたびintobject、(ヒープ上の)メモリの小さな部分が予約され、の値がintそこにコピーされます。これにはかなりの労力が必要です。キャストバックするたびに、.NET は最初にオブジェクトに実際に が含まれているかどうかを確認しint(オブジェクトには何でも含めることができるため)、値を にコピーして戻しますint。このチェックにも時間がかかります。

于 2013-05-01T17:40:46.513 に答える