在C#中,将ulong [64]转换为byte [512]更快?

时间:2010-01-25 16:41:49

标签: c# optimization

我有一种方法可以在for语句中使用二进制移位将ulongs转换为字节,但效率不是很高。有没有办法将大小为64的ulong数组直接转换为大小为512的字节数组?这是一段运行数千次的代码,我需要保存每毫秒,这样我就可以节省几秒钟。

编辑: 现在这就是我正在做的事情:

                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]);
                }

4 个答案:

答案 0 :(得分:4)

unsafe 
{
    fixed (ulong* src = ulongs) 
    {
        Marshal.Copy(new IntPtr((void*)src), bytes, 0, 512);
    }
}

这似乎有效。我不确定是否需要修复,但在定时测试期间我丢失了一整秒。

答案 1 :(得分:3)

执行此操作的最快方法可能是使用unsafefixed构造。这是一个例子:

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

编译上面的代码时,请不要忘记使用/unsafe编译器开关。

编辑:这是第一个代码片段的修改版本,它在我的机器上运行得更快:

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

答案 2 :(得分:0)

您可以使用struct和使用StructLayout属性的显式布局指令来强制变量占用相同的空间。

这样您可以使用ulong属性编写值,并使用byte数组属性读取它。当然,这假定byte数组真正占用了您期望的空间,并且它没有使用32位来保存8位信息。我将不得不在规范中查看,我还没有完成。

答案 3 :(得分:0)

使用System.Buffer助手类。

ulong[] buffer = null;
int byteLength = Buffer.ByteLength(buffer);
byte[] byteBuffer = new byte[byteLength];
Buffer.BlockCopy(buffer, 0, byteBuffer, 0, byteLength);