In C#, convert ulong[64] to byte[512] faster?
I have a way that converts ulongs to bytes using binary shifts in a for statement but it's not very time efficient. Is there a way to cast a ulong
array of size 64 directly into a byte array of size 512? This is a section of code that runs thousands of times and I need to save every millisecond so I can in turn save seconds.
Edit: Right now this is what I'm doing:
for (int k = 0; k < ulongs.Length; k++) {
bytes[(k << 3)] = (byte)(ulongs[k] >> 56);
bytes[(k << 3) + 1] = (byte)(ulongs[k] >> 48开发者_如何转开发);
bytes[(k << 3) + 2] = (byte)(ulongs[k] >> 40);
bytes[(k << 3) + 3] = (byte)(ulongs[k] >> 32);
bytes[(k << 3) + 4] = (byte)(ulongs[k] >> 24);
bytes[(k << 3) + 5] = (byte)(ulongs[k] >> 16);
bytes[(k << 3) + 6] = (byte)(ulongs[k] >> 8);
bytes[(k << 3) + 7] = (byte)(ulongs[k]);
}
unsafe
{
fixed (ulong* src = ulongs)
{
Marshal.Copy(new IntPtr((void*)src), bytes, 0, 512);
}
}
This seems to work. I'm not sure if fixed is required, but I lost an entire second during timed tests.
Probably the fastest way of doing it is to use unsafe
and fixed
constructions. Here's an example:
ulong[] ulongs = new ulong[64];
byte[] bytes = new byte[512];
unsafe
{
fixed (ulong* src = ulongs)
{
byte* pb = (byte*)src;
for (int i = 0; i < bytes.Count(); i++)
{
bytes[i] = *(pb + i);
}
}
}
Please do not forget to use /unsafe
compiler switch when compiling the code above.
Edit: here's modified version of the first code fragment, which runs much faster on my machine:
unsafe
{
fixed (ulong* src = ulongs)
{
fixed (byte *dst = bytes)
{
ulong* pl = (ulong*)dst;
for (int i = 0; i < ulongs.Count(); i++)
{
*(pl + i) = *(src + i);
}
}
}
}
You may be able to achieve this using a struct
and explicit layout instructions using the StructLayout
attribute to force variables to occupy the same space.
That way you could write the value using the ulong
property and read it using the byte
array property. This assumes, of course, that byte
array truly takes up the space you expect and that it isn't using 32 bits to hold the 8 bits of information. I'll have to look that up in the specification, which I have not done yet.
Use the System.Buffer helper class.
ulong[] buffer = null;
int byteLength = Buffer.ByteLength(buffer);
byte[] byteBuffer = new byte[byteLength];
Buffer.BlockCopy(buffer, 0, byteBuffer, 0, byteLength);
精彩评论