I need a fast way in C# leanguage of converting/casting array of bytes encoding one short (int16) value for 2bytes into float representation, as fast as possible. Performance bottleneck was method:
samples[sample] = (float)binraryReader.readInt16();
(huge ammount of IO calls so i had to convert to block read)
Basically i have file containing block of sound samples (~100-600 mb) of type of short, then, as i can only block read set of bytes, i need to construct short from each pair of bytes and then convert that short to float representation as i need to store samples as floats.
my current code looks somtething like this (about 2x performance improvement over method above, but still to long) :
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);
开发者_JAVA百科 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);
}
you can try this:
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++);
}
}
}
Did You try to use Bitwise operation
I do not know much about them but from Wiki and MY previous SO here what I had learned about it:
Bitwise operations are usually significantly faster than multiplication and division operations.
精彩评论