В момента оптимизирам приложение, една от операциите, които се правят много често, е четене и запис на двоичен файл. Имам нужда от 2 вида функции:
Set(byte[] target, int index, int value);
int Get(byte[] source, int index);
Тези функции са необходими за знакови и неподписани short, int и long в голям и малък ред.
Ето няколко примера, които направих, но имам нужда от оценка на предимствата и недостатъците:
първият метод използва Marshal, за да запише стойността в паметта на byte[], вторият използва обикновени указатели, за да постигне това, а третият използва 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:
първият използва Marshal за четене на стойността от byte[], вторият използва обикновени указатели, а третият отново използва 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);
}
проверката на границите трябва да се направи, но все още не е част от въпроса ми...
Ще се радвам, ако някой може да каже кой би бил най-добрият и най-бърз начин в този случай или да ми даде други решения, върху които да работя. За предпочитане е генерично решение
Току-що направих някои тестове за ефективност, ето резултатите:
Set Marshal: 45 ms, Set Pointer: 48 ms, Set BitConverter: 71 ms Get Marshal: 45 ms, Get Pointer: 26 ms, Get BitConverter: 30 ms
изглежда, че използването на указатели е бързият начин, но мисля, че Marshal и BitConverter правят някои вътрешни проверки... може ли някой да потвърди това?
Stopwatch
? - person mmx   schedule 10.01.2010