我並沒有真正管理應用程序的性能,但我對下面的場景很好奇。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