6


0

ファイルに書き出す必要がある一連のshort(short [])があります。 これを行うための最も速い方法は何ですか?

3 Answer


11


BinaryWriterを使う

static void WriteShorts(short []の値、文字列のパス){using(FileStream fs = new FileStream(path、FileMode.OpenOrCreate、FileAccess.Write)){using(BinaryWriter bw = new BinaryWriter(fs)){foreach(short value in) values){bw.Write(value); }}}}


2


Jon Bの答えに続いて、ファイルに他のデータが含まれている場合は、データの前に値の数を付加することをお勧めします。

すなわち:

static void WriteShorts(short [] values、string path){using(FileStream fs = new FileStream(path、FileMode.OpenOrCreate、FileAccess.Write)){using(BinaryWriter bw = new BinaryWriter(fs)){//数字を書く項目の数bw.Write(values.Length);

foreach(値の短い値){bw.Write(値); }}}}


1


  • BinaryFormatter は、プリミティブ型の配列(obj.GetType()。IsPrimitive)を使用した場合、実際には読み取りと書き込みの両方で 10倍高速*です。 DecimalやString(これは原始的なものではありません)用ではなく、確かに他の構造体やクラスではなく、恐ろしく遅いものではありません。

[Test]
public void TestShortArray(){var n = 100000000; var input = new short [n]; var r = new Random(); (var i = 0; i <n; i)に対して、入力[i] =(短)r。 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逆シリアル化:" sw.ElapsedMilliseconds "ms、" ms.ToArray()。Length "bytes"); Assert.AreEqual(入力、出力); sw.Reset(); using(var ms = new MemoryStream()){var bw = new BinaryWriter(ms、Encoding.UTF8、true); sw.Start(); bw.Write(input.Length); (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]; (var i = 0; i <length; i)の場合output [i] = br.ReadInt16(); sw.Stop(); Console.WriteLine( "BinaryReaderの逆シリアル化:" sw.ElapsedMilliseconds "ms、" ms.ToArray()。Length "bytes"); Assert.AreEqual(入力、出力); }}

出力:

BinaryFormatterシリアライズ:175 ms、200000028バイトBinaryFormatterデシリアライズ:79 ms、200000028バイトBinaryWriterシリアライズ:1499 ms、200000004バイトBinaryReaderデシリアライズ:1599 ms、200000004バイト

そのため、プリミティブ型の配列、または配列の配列でマルチディム配列の配列がない場合は、必ずBinaryFormatterを使用してください。 あなたのデータ型が例えばPoint3(double)であるならば、あなたはdouble []を埋めそして代わりにそれを直列化するべきです。 複合型/混合型、文字列、小数、特異値にはBinaryWriterのみを使用してください。

byte []を扱うとき、BinaryFormatterとBinaryWriterは同等に(そして非常に高速で)パフォーマンスがあります。 あなたが効果的な方法であなたの型をバイト配列に変換することができれば、あなたはこのようにさらに速いパフォーマンスを得るかもしれません。