C#中最快的方法是从文件中读取字节块并转换为float

转换/转换字节数组的C#leanguage需要一个快速的方法,将2字节的一个short(int16)值编码为float表示,尽可能快。 性能瓶颈是方法:

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

(巨大的IO调用,所以我不得不转换为块读取)

基本上我有包含声音样本块(~100-600 mb)类型的短文件,然后,因为我只能阻止读取字节集,我需要从每对字节构造短路然后将该短路转换为浮点数表示我需要将样本存储为浮点数。

我当前的代码看起来像这样(比上面的方法提高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); } 

你可以试试这个:

  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++); } } } 

您是否尝试使用Bitwise操作

我对它们了解不多,但是从Wiki和我之前的SO中我所了解到的内容:

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