dtb*_*dtb 9 c# arrays performance .net-4.5
以下简短但完整的示例程序
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 iterations/s ComplexClass 00:00:37.8199150 26,441,736 iterations/s SimpleStruct 00:00:12.3075100 81,254,571 iterations/s ComplexStruct 00:00:32.6140182 30,661,679 iterations/s
问题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 iterations/s ComplexClass 00:00:13.2505217 75,471,698 iterations/s SimpleStruct 00:00:14.8397693 67,389,986 iterations/s ComplexStruct 00:00:13.4821834 74,172,971 iterations/s
因此,几乎没有任何区别SimpleClass和ComplexClass,只有一小之间的差异SimpleStruct和ComplexStruct.但是,性能显著的下降SimpleClass和SimpleStruct.
编辑:现在T[] array = new T[1 << 16];:
SimpleClass 00:00:09.7477715 102,595,670 iterations/s ComplexClass 00:00:10.1279081 98,745,927 iterations/s SimpleStruct 00:00:12.1539631 82,284,210 iterations/s ComplexStruct 00:00:10.5914174 94,419,790 iterations/s
结果1<<15就像是1<<8,结果1<<17就像1<<20.
问题1的可能答案:
您的CPU一次将内存读入其缓存中.
使用较大的数据类型,您可以在每个缓存页面上放置更少的对象.即使您只编写一个32位值,仍然需要CPU缓存中的页面.使用较小的对象,您可以在下次需要从主内存中读取之前完成更多循环.
| 归档时间: | 
 | 
| 查看次数: | 320 次 | 
| 最近记录: |