Начнём с задачки. Имеется структура:
struct MyStruct { public Int16 Value; }
Требуется научится получать младший байт поля Value
. Но сделать это нужно так, чтобы обеспечить максимально возможную производительность.
struct MyStruct { public Int16 Value; public Byte LowByte { get { return (byte)(Value & 255); } } }
Но при таком подходе при каждом обращении к LowByte
на самом деле будет вызываться метод get_LowByte
, который на IL-уровне выглядит следующим образом:
.method public hidebysig specialname instance uint8 get_LowByte() cil managed { // Загружаем в стек указатель на текущий объект L_0000: ldarg.0 // Заменяем верхушку стека на значение свойства Value текущего объекта L_0001: ldfld int16 ConsoleApplication.MyStruct::Value // Кладём в стек 255 L_0006: ldc.i4 0xff // Достаём из стека два последних значения (Value и 255) и кладём обратно их конъюнкцию L_000b: and // Выполняем приведение типа к byte L_000c: conv.u1 // Возвращаем управление L_000d: ret }
Итого имеем 6 команд метода + накладки на вызов функции. Есть более быстрый способ, который находится в пространстве имён System.Runtime.InteropServices
. Суть в том, что в C# есть возможность явно указать в каком порядке и с каким смещением размещать поля структуры. Для этого нужно пометить структуру атрибутом StructLayout
с параметром LayoutKind.Explicit
. После этого для каждого поля можно вручную прописать смещение. Таким образом, наша задачка решается так:
[StructLayout(LayoutKind.Explicit)] struct MyStruct { [FieldOffset(0)] public Int16 Value; [FieldOffset(0)] public Byte LowByte; }
Теперь вместо генерации вспомогательного метода для получения младшего байта необходимое значение берётся непосредственно из памяти. Следующий код демонстрирует использование структуры:
var s = new MyStruct(); s.Value = 256 + 100; Console.WriteLine(s.LowByte); // 100
Сказанное выше вовсе не означает, что теперь нужно срочно переписывать все ваши структуры, вручную размещая поля. Платформа .NET и сама с этим прекрасно справляется. Но если есть жестокие требования по производительности, то данный метод может помочь.
Комментариев нет:
Отправить комментарий