2010-06-04 14 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

相关问题