值类型与引用类型-性能
本文关键字:性能 引用类型 类型 | 更新日期: 2023-09-27 18:11:46
我正忙于阅读Jon Skeet的优秀著作《深度C#》。他在关于装箱和开箱的章节中提到,使用装箱对象的开销很小,可以想象会在足够大的范围内产生性能差异。
因此,我编写了自己的基准测试,使用for循环将从1到100000000的所有数字相加。在一种情况下,我使用Int32
,然后使用int
,然后转换为object
,再转换回int
。将所有测试重复10次,取平均值。结果(以秒为单位(:
Int32平均值:0.333
int平均值:0.326
对象平均值:1.061
Int32
和int
没有太大区别,但装箱/拆箱的时间要长3倍!
所以请帮我理解一下:当你把int
转换成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());
c#关键字int
是System.Int32
的别名。所以他们的表现完全一样。
当然,在测量过程中总是会有波动,因为您的机器也在执行其他任务。
每次将int
强制转换为object
时,都会保留一小块内存(堆上(,并将int
的值复制到其中。这需要付出相当大的努力。每次将其强制转换回时,.NET将首先检查对象是否真的包含int
(因为对象可以包含任何内容(,然后将值复制回int
。此检查也需要时间。