2010-06-04 11 views
5

Necesito una forma rápida en C# leanguage de convertir/moldear una matriz de bytes que codifica un valor corto (int16) para 2bytes en representación flotante, tan rápido como sea posible. cuello de botella era el método:Manera más rápida en C# para leer el bloque de bytes del archivo y convertirlo a float []

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

(enorme ammount de IO llama así que tuve que convertir en bloque de lectura)

Básicamente tengo archivo que contiene el bloque de muestras de sonido (~ 100-600 MB) de tipo de cortocircuito, entonces, como solo puedo bloquear el conjunto de bytes de lectura, necesito construir un resumen de cada par de bytes y luego convertir esa breve a la representación flotante ya que necesito almacenar muestras como flotantes.

mi código actual se ve somtething como esto (aproximadamente 2x mejora del rendimiento sobre método anterior, pero aún a tiempo):

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

Respuesta

1

puede probar esto:

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

Gracias, parece que el hardware del disco es limitado, pero todavía tengo unos ~ 10 porcentajes de tiempo, así que creo que es bueno ahora, ya que no puedo imaginar algo más rápido: P – Oscar

0

¿trató de utilizar Bitwise operation

No sé mucho sobre ellos, pero de Wiki y MY previous SO aquí lo que había aprendido al respecto:

Las operaciones a nivel de bit suelen ser significativamente más rápidas que las operaciones de multiplicación y división.

+1

Ya está usando un operador de cambio a la izquierda en su segundo ejemplo. – Hinek

Cuestiones relacionadas