あなたが実際にここでやっているように見えるのは、手動ボクシングとインバイトボクシングの比較です。 inbuiltボクシングは高度に最適化されています - だから私はここで大きな違いを見込むとは思っていないが、我々は確認することができます。重要なことに、両方とも同じメモリへの影響があることに注意してください。int
フィールドを含む1つのヒープオブジェクト、int
の囲み/折り返し。
次の例は、かなり近似しています。私は、したがって、それを直接/組み込みの方法で囲むと言うでしょう。
注:デバッガなしで(理想的にはコマンドラインで)リリースモードで実行してください。最初の呼び出しはJITをすべてプレJITすることです。
using System;
using System.Diagnostics;
public sealed class IntObj
{
public readonly int Value;
public IntObj(int value)
{
Value = value;
}
}
static class Program
{
static void Main()
{
Run(1, 0, false);
Run(100000, 500, true);
Console.ReadKey();
}
static void Run(int length, int repeat, bool report)
{
var data = new object[length];
int chk = 0;
var watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = i;
chk += i;
}
}
watch.Stop();
if(report) Console.WriteLine("Box: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
chk += (int) data[i];
}
}
watch.Stop();
if (report) Console.WriteLine("Unbox: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = new IntObj(i);
chk += i;
}
}
watch.Stop();
if (report) Console.WriteLine("Wrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
chk = 0;
watch = Stopwatch.StartNew();
for (int j = 0; j < repeat; j++)
{
for (int i = 0; i < data.Length; i++)
{
chk += ((IntObj)data[i]).Value;
}
}
watch.Stop();
if (report) Console.WriteLine("Unwrap: {0}ms (chk: {1})", watch.ElapsedMilliseconds, chk);
}
}
私はそれを測定していませんが、プリミティブが速いと言います。オブジェクトにオーバーヘッドがあります。しかし、この場合、私は可読性がはるかに重要な手段だと思います。 Cpuのサイクルは脳のサイクルよりもずっと安価です –