Potrzebuję szybki sposób w języku C# konwersji/castingu tablicy bajtów kodujących jedną krótką (int16) wartość dla 2 bajtów na reprezentację swobodną, tak szybko jak to możliwe. Wydajność gardłem była metoda:Najszybszy sposób w C# do odczytu bloku bajtów z pliku i konwersji do float []
samples[sample] = (float)binraryReader.readInt16();
(ogromny ammount IO wzywa więc musiałem konwertować do blokowania odczytu)
Zasadniczo mam plik zawierający blok próbek dźwiękowych (~ 100-600 MB) typ short, a następnie, ponieważ mogę tylko blokować odczytywany zestaw bajtów, muszę skonstruować krótko z każdej pary bajtów, a następnie przekonwertować tę krótką reprezentację float, ponieważ muszę przechowywać próbki jako float.
mój obecny kod wygląda somtething tak (około 2x wzrost wydajności w stosunku metody powyżej, ale jeszcze długa):
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);
}
Dzięki, wydaje mi się, że sprzęt z dyskami im jest ograniczony, ale wciąż mam około 10 proc. Czasu, więc myślę, że jest teraz dobry, ponieważ nie mogę wyobrazić sobie niczego szybciej: P – Oscar