В настоящее время я оптимизирую приложение, одна из операций, которые выполняются очень часто, - это чтение и запись двоичных файлов. Мне нужно два типа функций:
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
Эти функции необходимы для подписанных и unsigned short, int и long в больших и маленьких порядках.
Вот несколько примеров, которые я сделал, но мне нужна оценка преимуществ и недостатков:
первый метод использует маршал для записи значения в память байта [], второй использует простые указатели для выполнения этого, а третий использует 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);
}
И вот методы Read/Get:
первый использует маршал для чтения значения из байта [], второй использует простые указатели, а третий использует битконвертер снова:
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 мс, установить битконвертер: 71 мс Get Marshal: 45 ms, Get Pointer: 26 ms, Get BitConverter: 30 мс
кажется, что использование указателей - это быстрый способ, но я думаю, что Marshal и BitConverter делают некоторую внутреннюю проверку... может ли кто-нибудь проверить это?