2014-03-12 48 views
0

我最近做了一些代碼的一些分析,發現最大的CPU使用率正在被調用消耗BitConverter如:爲什麼BitConverter比直接按位操作慢?

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

切換到像時:

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

我注意到一個性能的巨大提高。

我的問題是爲什麼使用BitConverter如此慢?我會假定BitConverter實質上是在內部進行相同的位移。

+0

什麼是「巨大的進步」?沒有函數調用的開銷總是會有所作爲。由於這是一個非常短的函數,所以函數開銷會相對較大。當你允許內聯擴展(編譯器優化)時,差異(大部分)會消失嗎? – Floris

回答

6

BitConverter的調用涉及新對象的分配和初始化。然後調用一個方法。在方法調用內部是參數驗證。

按位操作可以編譯到少數CPU操作碼,然後按或鍵進行轉換。

後者肯定會更快,因爲它消除了前者的所有開銷。

3

你可以看看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)));       
       } 
      } 
    } 
} 
相關問題