我并没有真正管理应用程序的性能,但我对下面的场景很好奇。C#结构布局和意外的基准标记结果?
对于Structs,默认情况下,C#编译器生成布局LayoutType。顺序。这意味着这些字段应该保持程序员定义的顺序。我相信这是为了支持与非托管代码的互操作性。然而,大多数用户定义的Struct与互操作性无关。为了获得更好的性能,我已经读过,我们可以明确指定LayoutKind.Auto,并让CLR决定最佳布局。为了测试这个,我想在这两个布局上做一个快速的基准测试。但是我的结果表明默认布局(LayoutType.Sequnetial)比显式布局(LayoutType.Auto)快一点。我期待着相反的情况。
下面是我在我的机器上运行(x86上运行.NET 4)
//uses LayoutKind.Sequence by default
public struct StructSeq
{
private readonly Byte mb;
private readonly Int16 mx;
public string a;
public string b;
public string c;
public string d;
}
[StructLayout(LayoutKind.Auto)]
public struct StructAuto
{
private readonly Byte mb;
private readonly Int16 mx;
public string a;
public string b;
public string c;
public string d;
}
public sealed class Program
{
public static void Main()
{
StructSeq sq = new StructSeq();
Stopwatch sw1 = new Stopwatch();
sw1.Start();
for (int i = 0; i < 10000; i++)
{
sq = ProcessStructSeq(sq);
}
sw1.Stop();
Console.WriteLine("Struct LayoutKind.Sequence (default) {0}", sw1.Elapsed.TotalMilliseconds);
StructAuto so = new StructAuto();
Stopwatch sw2 = new Stopwatch();
sw2.Start();
for (int i = 0; i < 10000; i++)
{
so = ProcessStructAuto(so);
}
sw2.Stop();
Console.WriteLine("Struct LayoutKind.Auto (explicit) {0}", sw2.Elapsed.TotalMilliseconds);
Console.ReadLine();
}
public static StructSeq ProcessStructSeq(StructSeq structSeq)
{
structSeq.a = "1";
structSeq.b = "2";
structSeq.c = "3";
structSeq.d = "4";
return structSeq;
}
public static StructAuto ProcessStructAuto(StructAuto structAuto)
{
structAuto.a = "1";
structAuto.b = "2";
structAuto.c = "3";
structAuto.d = "4";
return structAuto;
}
}
下面是一个示例的结果我得到我的机器上(x86上运行.NET 4)
测试结构LayoutKind.Sequence(默认值)0.7488
结构LayoutKind.Auto(明确的)0.7643
我跑这个测试多次,我总是得到结构LayoutKind.Sequence(默认)<结构LayoutKind.Auto(明确的)
即使是微毫秒的差异,我很期待结构LayoutKind.Auto(明确)低于Struct LayoutKind.Sequence(默认)。
有谁知道这个的原因?还是我的基准测试不够准确,给我正确的结果?
谢谢罗伯特。正如你所建议的,我已经优化了基准,并看到了预期的结果。更改如下:将迭代次数增加到几百万,在x86发行版中运行,并将结构作为参考。 – Spock 2012-02-26 10:04:51