开发者

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜