Qual è il modo migliore per scrivere una matrice su un file in C #?

Ho una serie di cortometraggi (breve []) che ho bisogno di scrivere su un file. Qual è il modo più veloce per farlo?

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

Seguendo la risposta di Jon B, se il tuo file contiene altri dati, potresti voler precedere i dati con il conteggio dei valori.

vale a dire:

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

BinaryFormatter è infatti circa 10 volte più veloce sia per le letture che per le scritture quando viene utilizzato con matrici di tipi primitivi (obj.GetType (). IsPrimitive), cioè non per Decimal e String (che non sono primitivi) e certamente non per qualsiasi altra struttura o class dove invece è orribilmente 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); } } 

Produzione:

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

Quindi usa BinaryFormatter ogni volta che hai una matrice di un tipo primitivo, o array di matrici ma non array multi-dim (!). Se il tuo tipo di dati è ad esempio Point3 (double) devi riempire un double [] e serializzare quello invece. Utilizzare solo BinaryWriter per tipi complessi / misti, stringhe, decimali e valori singolari.

Quando si ha a che fare con byte [], BinaryFormatter e BinaryWriter sono ugualmente performanti (e molto veloci). Se riesci a convertire il tuo tipo in array di byte in modo efficace, potresti ottenere prestazioni ancora più veloci in questo modo.