Я провел исследование времени, необходимого для сериализации базового типа в байтовый массив. Я сделал это для случая, когда у вас уже есть массив и смещение, куда вы хотите поместить свои данные. Я думаю, что это действительно важный случай по сравнению с теоретическим получить массив из 4 байтов, потому что когда вы сериализуете что-то, это именно то, что вам нужно. Я понял, что ответ на то, какой метод быстрее, зависит от того, какой тип вы хотите сериализовать. Я пробовал несколько методов:
- Небезопасная ссылка с дополнительной проверкой переполнения буфера
- GetBytes + последующий Buffer.BulkCopy (это по сути то же самое, что 1 плюс накладные расходы)
- Прямое назначение со смещением (
m_Bytes[offset] = (byte)(value >> 8)
- Прямое присваивание со сдвигом и поразрядно &
m_Bytes[offset] = (byte)((i >> 8) & 0xFF)
Я выполнил весь тест 10 миллионов раз. Ниже приведены результаты в миллисекундах
Long Int Short Byte Float Double
1 29 32 31 30 29 34
2 209 233 220 212 208 228
3 63 24 13 8 24 44
4 72 29 14
Как вы можете видеть, небезопасный способ намного быстрее для длинных и двойных (неподписанные версии примерно такие же, как их подписанные версии, поэтому их нет в таблице). Для short / int / float самый быстрый способ - это 2/4/4 назначения со смещением. Для байта самое быстрое, очевидно, простое назначение. Что касается первоначального вопроса - способ назначения является лучшим. Вот пример такой функции самым быстрым способом:
public static void WriteInt(byte[] buffer, int offset, int value)
{
m_BytesInt[offset] = (byte)(value >> 24);
m_BytesInt[offset + 1] = (byte)(value >> 16);
m_BytesInt[offset + 2] = (byte)(value >> 8);
m_BytesInt[offset + 3] = (byte) value;
}
P.S. Тесты выполнялись в среде x64 с кодом, скомпилированным для любого процессора (который был x64 при запуске) в режиме выпуска.