2010-06-04 15 views
5

我需要一種快速的方式在C#語言中將字節數組編碼一個short(int16)值的2字節的字節轉換/儘可能。性能瓶頸是方法:在C#中最快的方式來讀取文件中的字節塊並轉換爲浮點數[]

samples[sample] = (float)binraryReader.readInt16();

(IO的巨大ammount的要求,所以我不得不轉換成塊讀取)

基本上我有一個包含聲音樣本(〜100-600 MB)的塊文件短的類型,然後,因爲我只能阻止讀取字節集,我需要從每對字節構造短,然後將該短的轉換爲浮點表示,因爲我需要將樣本存儲爲浮點數。

我當前的代碼看起來somtething像這樣(在方法約2倍的性能提升上面,但還是長):

float[] samples = new float[_samplesPerSplit]; 
    byte[] data = new byte[_samplesPerSplit * 2]; 

    for (int c = 0; c < numberOfChunks; c += 1) 
    { 
     br.Read(data, 0, _samplesPerSplit * 2); 

     fixed (byte* bytePtr = data) 
     { 
      fixed (float* floatPtr = samples) 
      { 
       byte* rPos = bytePtr; 
       float* fPos = floatPtr; 

       byte byte0; 
       byte byte1; 
       short sampleShort; 

       for (int sample = 0; sample < _samplesPerSplit; sample += 1) 
       { 
        byte1 = *(rPos++); 
        byte0 = *(rPos++); 

        // I occasionaly get 
        //   "Negating the minimum value of a 
        //   twos complement number is invalid" 
        // error if i skip this check, but it slows down 
        // whole process even more 
        if (byte0 == 128 && byte1 == 0) 
        { 
         sampleShort = 32767; 
        } 
        else 
        { 
         sampleShort = (short)(((ushort)(byte0)) << 8 | ((ushort)(byte1))); 
        } 

        *(fPos++) = (float)sampleShort; 
       } 
      } 
     } 
     ProcessChunk(samples); 
    } 

回答

1

你可以試試這個:

fixed (byte* bytePtr = data) 
    { 
     fixed (float* floatPtr = samples) 
     { 
      short* rPos = (short*)bytePtr; 
      float* fPos = floatPtr; 

      for (int sample = 0; sample < _samplesPerSplit; sample += 1) 
      { 
       *fPos++ = (float)(*rPos++); 
      } 

     } 
    } 
+0

感謝,似乎im光盤硬件有限,但我仍然得到了一些約10左右的百分比,所以我認爲它現在好了,因爲我無法想象任何更快:P – Oscar 2010-06-04 15:49:22

0

你嘗試使用Bitwise operation

我不太瞭解他們,但從Wiki和我的previous SO這裏我瞭解了它:

按位運算通常比乘法和除法運算快得多。

+1

他已經在他的左移操作符第二個例子。 – Hinek 2010-06-04 15:33:49

相關問題