以下简短但完整的示例程序
const long iterations = 1000000000;
T[] array = new T[1 << 20];
for (int i = 0; i < array.Length; i++)
{
array[i] = new T();
}
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < iterations; i++)
{
array[i % array.Length].Value0 = i;
}
Console.WriteLine("{0,-15} {1} {2:n0} iterations/s",
typeof(T).Name, sw.Elapsed, iterations * 1000d / sw.ElapsedMilliseconds);
替换T
为以下类型
class SimpleClass struct SimpleStruct
{ {
public int Value0; public int Value0;
} }
class ComplexClass struct ComplexStruct
{ {
public int Value0; public int Value0;
public int Value1; public int Value1;
public int Value2; public int Value2;
public int Value3; public int Value3;
public int Value4; public int Value4;
public int Value5; public int Value5;
public int Value6; public int Value6;
public int Value7; public int Value7;
public int Value8; public int Value8;
public int Value9; public int Value9;
public int Value10; public int Value10;
public int Value11; public int Value11;
} }
在我的机器上产生以下有趣的结果(Windows 7 .NET 4.5 32 位)
SimpleClass 00:00:10.4471717 95,721,260 次迭代/秒 ComplexClass 00:00:37.8199150 26,441,736 次迭代/秒 SimpleStruct 00:00:12.3075100 81,254,571 次迭代/秒 ComplexStruct 00:00:32.6140182 30,661,679 次迭代/秒
问题1:为什么ComplexClass
比 慢这么多SimpleClass
?经过的时间似乎随着类中字段的数量线性增加。写入具有很多字段的类的第一个字段与写入只有一个字段的类的第一个字段应该没有太大区别,不是吗?
问题2:为什么ComplexStruct
比 慢SimpleStruct
?看一下 IL 代码,i
它直接写入数组,而不是写入本地实例ComplexStruct
,然后复制到数组中。所以应该不会因为复制更多字段而产生开销。
额外的问题:为什么ComplexStruct
比 快ComplexClass
?
编辑:用更小的数组更新了测试结果,T[] array = new T[1 << 8];
:
SimpleClass 00:00:13.5091446 74,024,724 次迭代/秒 ComplexClass 00:00:13.2505217 75,471,698 次迭代/秒 SimpleStruct 00:00:14.8397693 67,389,986 次迭代/秒 ComplexStruct 00:00:13.4821834 74,172,971 次迭代/秒
所以和之间几乎没有区别,SimpleClass
和之间ComplexClass
只有很小的区别。但是,和的性能显着下降。SimpleStruct
ComplexStruct
SimpleClass
SimpleStruct
编辑:现在有了T[] array = new T[1 << 16];
:
SimpleClass 00:00:09.7477715 102,595,670 次迭代/秒 ComplexClass 00:00:10.1279081 98,745,927 次迭代/秒 SimpleStruct 00:00:12.1539631 82,284,210 次迭代/秒 ComplexStruct 00:00:10.5914174 94,419,790 次迭代/秒
for 的结果1<<15
是 like 1<<8
,而 for 的结果1<<17
是 like 1<<20
。