优化C#代码片段

Eri*_* J. 5 c# unchecked micro-optimization

我正在分析一些C#代码.以下方法是最昂贵的方法之一.出于这个问题的目的,假设微观优化是正确的.有没有办法提高这种方法的性能?

将输入参数更改pulong[]将导致宏效率低下.

static ulong Fetch64(byte[] p, int ofs = 0)
{
    unchecked
    {
        ulong result = p[0 + ofs] + 
            ((ulong) p[1 + ofs] <<  8) + 
            ((ulong) p[2 + ofs] << 16) + 
            ((ulong) p[3 + ofs] << 24) + 
            ((ulong) p[4 + ofs] << 32) + 
            ((ulong) p[5 + ofs] << 40) + 
            ((ulong) p[6 + ofs] << 48) + 
            ((ulong) p[7 + ofs] << 56);
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

Nic*_*rey 5

为什么不使用BitConverter?我必须相信微软花了一些时间调整代码.此外,它还处理endian问题.

以下是BitConverter如何将byte []转换为long/ulong(ulong将其转换为signed,然后将其转换为unsigned):

[SecuritySafeCritical]
public static unsafe long ToInt64(byte[] value, int startIndex)
{
  if (value == null)
  {
    ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
  }
  if (((ulong) startIndex) >= value.Length)
  {
    ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
  }
  if (startIndex > (value.Length - 8))
  {
    ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
  }
  fixed (byte* numRef = &(value[startIndex]))
  {
    if ((startIndex % 8) == 0)
    {
      return *(((long*) numRef));
    }
    if (IsLittleEndian)
    {
      int num  = ((numRef[0] | (numRef[1] << 8)) | (numRef[2] << 0x10)) | (numRef[3] << 0x18);
      int num2 = ((numRef[4] | (numRef[5] << 8)) | (numRef[6] << 0x10)) | (numRef[7] << 0x18);
      return (((long) ((ulong) num)) | (num2 << 0x20));
    }
    int num3 = (((numRef[0] << 0x18) | (numRef[1] << 0x10)) | (numRef[2] << 8)) | numRef[3];
    int num4 = (((numRef[4] << 0x18) | (numRef[5] << 0x10)) | (numRef[6] << 8)) | numRef[7];
    return (((long) ((ulong) num4)) | (num3 << 0x20));
  }
}
Run Code Online (Sandbox Code Playgroud)

我怀疑一次转换一个32位字是为了32位效率.32位CPU上没有64位寄存器意味着处理64位整数要贵得多.

如果你确定你的目标是64位硬件,那么一举进行转换可能会更快.