2008-10-22 18 views
6

Tengo una serie de cortos (short []) que debo escribir en un archivo. ¿Cuál es la forma más rápida de hacer esto?¿Cuál es la mejor manera de escribir una matriz corta [] en un archivo en C#?

+0

Me acabo de dar cuenta de que "una serie de pantalones cortos" suena algo gracioso. Lo siento, esta es una pregunta real. – MusiGenesis

+0

Ayudaría si mencionas en qué formato quieres que estén. Binario, legible para humanos, coma separada, uno por línea ... – tvanfosson

Respuesta

11

Uso del BinaryWriter

static void WriteShorts(short[] values, string path) 
    { 
     using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) 
     { 
      using (BinaryWriter bw = new BinaryWriter(fs)) 
      { 
       foreach (short value in values) 
       { 
        bw.Write(value); 
       } 
      } 
     } 
    } 
+0

Aquí hay una mejor manera: convierte tu matriz corta en una matriz de bytes usando Buffer.BlockCopy y luego serializar eso en su lugar. Mucho más rápido (incluida la parte de conversión). O utilice BinaryFormatter hacia arriba, que es muy rápido para matrices con elementos primitivos. –

2

El seguimiento de la respuesta de Jon B, si el archivo contiene otros datos, es posible que desee prefijar los datos con la cuenta de valores.

es decir:

static void WriteShorts(short[] values, string path) 
{ 
    using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write)) 
    { 
     using (BinaryWriter bw = new BinaryWriter(fs)) 
     { 
      // Write the number of items 
      bw.Write(values.Length); 

      foreach (short value in values) 
      { 
       bw.Write(value); 
      } 
     } 
    } 
} 
1

BinaryFormatter trata de hecho de 10 veces más rápido tanto para lectura y escritura cuando se utiliza con arrays de tipos primitivos, es decir, no por (obj.GetType() IsPrimitive.) Decimal y String (que no son primitivos) y ciertamente no para ninguna otra estructura o clase donde, en cambio, es terriblemente lento.

[Test] 
public void TestShortArray() 
{ 
    var n = 100000000; 
    var input = new short[n]; 
    var r = new Random(); 
    for (var i = 0; i < n; i++) input[i] = (short)r.Next(); 
    var bf = new BinaryFormatter(); 
    var sw = new Stopwatch(); 
    using (var ms = new MemoryStream()) 
    { 
    sw.Start(); 
    bf.Serialize(ms, input); 
    sw.Stop(); 
    Console.WriteLine("BinaryFormatter serialize: " + 
     sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes"); 
    sw.Reset(); 
    ms.Seek(0, SeekOrigin.Begin); 
    sw.Start(); 
    var output = (short[])bf.Deserialize(ms); 
    sw.Stop(); 
    Console.WriteLine("BinaryFormatter deserialize: " + 
     sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes"); 
    Assert.AreEqual(input, output); 
    } 
    sw.Reset(); 
    using (var ms = new MemoryStream()) 
    { 
    var bw = new BinaryWriter(ms, Encoding.UTF8, true); 
    sw.Start(); 
    bw.Write(input.Length); 
    for (var i = 0; i < input.Length; i++) bw.Write(input[i]); 
    sw.Stop(); 
    Console.WriteLine("BinaryWriter serialize: " + 
     sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes"); 
    sw.Reset(); 
    ms.Seek(0, SeekOrigin.Begin); 
    var br = new BinaryReader(ms, Encoding.UTF8, true); 
    sw.Start(); 
    var length = br.ReadInt32(); 
    var output = new short[length]; 
    for (var i = 0; i < length; i++) output[i] = br.ReadInt16(); 
    sw.Stop(); 
    Console.WriteLine("BinaryReader deserialize: " + 
     sw.ElapsedMilliseconds + " ms, " + ms.ToArray().Length + " bytes"); 
    Assert.AreEqual(input, output); 
    } 
} 

Salida:

BinaryFormatter serialize: 175 ms, 200000028 bytes 
BinaryFormatter deserialize: 79 ms, 200000028 bytes 
BinaryWriter serialize: 1499 ms, 200000004 bytes 
BinaryReader deserialize: 1599 ms, 200000004 bytes 

Así que utilice BinaryFormatter cada vez que tenga una matriz de un tipo primitivo, o matriz de matrices, pero no matrices multi-dim (!). Si su tipo de datos es, por ejemplo, Point3 (doble), debe completar un doble [] y serializarlo en su lugar. Utilice únicamente BinaryWriter para tipos complejos/mixtos, cadenas, decimales y valores singulares.

Al tratar con byte [], BinaryFormatter y BinaryWriter tienen el mismo rendimiento (y son muy rápidos). Si puede convertir su tipo a matriz de bytes de una manera efectiva, puede obtener un rendimiento aún más rápido de esta manera.

Cuestiones relacionadas