【问题标题】:Why is BitConverter slower than doing the bitwise operations directly?为什么 BitConverter 比直接进行按位运算要慢?
【发布时间】:2014-03-12 14:47:08
【问题描述】:

我最近对一些代码进行了一些分析,发现对 BitConverter 的调用消耗了最大的 CPU 使用率,例如:

return BitConverter.ToInt16(new byte[] { byte1, byte2 });

当切换到类似的东西时:

return (short)(byte1 << 8 | byte2);

我注意到性能有了很大的提升。

我的问题是为什么使用 BitConverter 这么慢?我会假设 BitConverter 本质上是在内部进行相同类型的位移。

【问题讨论】:

  • 什么是“巨大的改进”?没有函数调用的开销总是会有所作为。由于这是一个很短的函数,所以函数开销会比较大。当您允许内联扩展(编译器优化)时,差异是否(大部分)消失了?

标签: c# bit-shift bitconverter


【解决方案1】:

BitConverter 的调用涉及新对象的分配和初始化。然后是方法调用。在方法调用内部是参数验证。

可以将按位运算直接编译为少量 CPU 操作码以进行移位,然后是或。

后者肯定会更快,因为它消除了前者的所有开销。

【讨论】:

    【解决方案2】:

    您可以查看reference source,发现它还有一些额外的问题需要担心,尤其是参数验证和字节序问题:

    public static unsafe short ToInt16(byte[] value, int startIndex) {
         if( value == null)  {
              ThrowHelper.ThrowArgumentNullException(ExceptionArgument.value);
         }
    
         if ((uint) startIndex >= value.Length) {
              ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.startIndex, ExceptionResource.ArgumentOutOfRange_Index);
         }
    
         if (startIndex > value.Length -2) {
              ThrowHelper.ThrowArgumentException(ExceptionResource.Arg_ArrayPlusOffTooSmall);
         }
         Contract.EndContractBlock();
    
         fixed( byte * pbyte = &value[startIndex]) {
              if( startIndex % 2 == 0) { // data is aligned 
                  return *((short *) pbyte);
              }
              else {
                  if( IsLittleEndian) { 
                       return (short)((*pbyte) | (*(pbyte + 1) << 8)) ;
                  }
                  else {
                       return (short)((*pbyte << 8) | (*(pbyte + 1)));                        
                  }
              }
         }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-31
      • 2014-04-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多