В настоящее время я оптимизирую приложение, одна из операций, которая выполняется очень часто, - чтение и запись двоичного файла. Мне нужно 2 типа функций:
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
Эти функции необходимы для подписанных и беззнаковых коротких, целых и длинных в порядке старшего и младшего байтов.
Вот несколько примеров, которые я привел, но мне нужна оценка преимуществ и недостатков:
первый метод использует Marshal для записи значения в память байта [], второй использует простые указатели для достижения этой цели, а третий использует BitConverter и BlockCopy для этого
unsafe void Set(byte[] target, int index, int value)
{
fixed (byte* p = &target[0])
{
Marshal.WriteInt32(new IntPtr(p), index, value);
}
}
unsafe void Set(byte[] target, int index, int value)
{
int* p = &value;
for (int i = 0; i < 4; i++)
{
target[offset + i] = *((byte*)p + i);
}
}
void Set(byte[] target, int index, int value)
{
byte[] data = BitConverter.GetBytes(value);
Buffer.BlockCopy(data, 0, target, index, data.Length);
}
А вот методы чтения / получения:
первый использует Marshal для чтения значения из байта [], второй использует простые указатели, а третий снова использует BitConverter:
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return Marshal.ReadInt32(new IntPtr(p), index);
}
}
unsafe int Get(byte[] source, int index)
{
fixed (byte* p = &source[0])
{
return *(int*)(p + index);
}
}
unsafe int Get(byte[] source, int index)
{
return BitConverter.ToInt32(source, index);
}
необходимо проверить границы, но это еще не часть моего вопроса ...
Я был бы рад, если бы кто-то мог сказать, что было бы лучшим и быстрым способом в этом случае, или дать мне некоторые другие решения для работы. Общее решение было бы предпочтительным
Я только что провел тестирование производительности, вот результаты:
Установить маршала: 45 мс, Установить указатель: 48 мс, Установить BitConverter: 71 мс
Получить маршал: 45 мс, Получить указатель: 26 мс, Получить BitConverter: 30 мс
кажется, что использование указателей - быстрый способ, но я думаю, что Marshal и BitConverter проводят внутреннюю проверку ... может кто-нибудь это проверить?