0

我正忙着阅读 Jon Skeet 的优秀书籍C# In Depth。他在有关装箱和拆箱的部分中提到,使用装箱对象的开销很小,可以想象,在足够大的规模上可能会产生性能差异。

所以我编写了自己的基准测试,使用 for 循环将 1 到 100,000,000 的所有数字相加。在一种情况下,我使用了Int32then int,然后我转换为object并转换回int. 将所有测试重复 10 次并取平均值。结果(以秒为单位):

Int32 平均值:0.333

整数平均:0.326

对象平均:1.061

Int32和之间没有太大区别int,但装箱/拆箱时间要长 3 倍!

所以请在这里帮助我理解:当您将 anint转换为 an时object,它与将其转换为 不一样Int32吗? DotNetPerls断言这int实际上只是一个别名Int32- 但如果是这样的话,那么为什么int总是比 执行得快Int32,即使只是稍微如此呢?

编辑:应普遍要求,这是基准代码:

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# 关键字intSystem.Int32. 所以表现完全一样。

当然,测量过程中总会有波动,因为您的机器也在做其他任务。

每次当您将 anint转换为一object小块内存(在堆上)时,都会保留并将其值int复制到那里。这需要相当的努力。每次您将其转换回时,.NET 都会首先检查您的对象是否实际包含一个int(因为一个对象可以包含任何内容),然后将该值复制回int. 这项检查也需要时间。

于 2013-05-01T17:40:46.513 回答