2010-06-04 9 views
5

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

Odpowiedz

1

można spróbować to:

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

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

0

Próbowałeś użyć Bitwise operation

Niewiele o nich wiem, ale z Wiki i MY previous SO o tym, czego się dowiedziałem:

Operacje bitowe są zwykle znacznie szybsze niż operacje mnożenia i dzielenia.

+1

Używa już operatora lewej zmiany w swoim drugi przykład. – Hinek

Powiązane problemy