Начнём с задачки. Имеется структура:
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 и сама с этим прекрасно справляется. Но если есть жестокие требования по производительности, то данный метод может помочь.
Комментариев нет:
Отправить комментарий