Я не очень микро-управляю производительностью приложения, но меня интересует следующий сценарий.
Для Structs по умолчанию компилятор C # создает макет LayoutType.Последовательная.Это означает, что поля должны оставаться в порядке, определенном программистом.Я считаю, что это для поддержки взаимодействия с неуправляемым кодом.Однако большинство пользовательских структур не имеют ничего общего с совместимостью.Я читал, что для повышения производительности мы можем явно указать 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)
Struct LayoutKind.Sequence (по умолчанию) 0,7488
Struct LayoutKind.Auto (явный) 0,7643
Я запускал этот тест несколько раз и всегда получаю Struct LayoutKind.Sequence (по умолчанию)
Несмотря на разницу в микросекундах, я ожидаю, что Struct LayoutKind.Auto (явное) будет ниже, чем Struct LayoutKind.Sequence (по умолчанию).
Кто-нибудь знает причину этого?Или это мой сравнительный анализ недостаточно точен, чтобы дать мне правильный результат?