を使用してBinaryFormatter
、フロートのかなり単純な多次元配列をシリアル化しますが、問題は任意のプリミティブ型で発生すると思われます。私の多次元アレイには10000x16フロート(160k)が含まれており、PCでのシリアル化は最大8 MB /秒で実行されます(60秒のベンチマークでSSDドライブに最大500 MBを書き込みます)。コード:
Stopwatch stopwatch = new Stopwatch();
float[,] data = new float[10000 , 16]; // Two-dimensional array of 160,000 floats.
// OR
float[] data = new float[10000 * 16]; // One-dimensional array of 160,000 floats.
var formatter = new BinaryFormatter();
var stream = new FileStream("C:\\Temp\\test_serialization.data", FileMode.Create, FileAccess.Write);
// Serialize to disk the array 1000 times.
stopwatch.Reset();
stopwatch.Start();
for (int i = 0; i < 1000; i++)
{
formatter.Serialize(stream, data);
}
stream.Close();
stopwatch.Stop();
TimeSpan ts = stopwatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds);
Console.WriteLine("Runtime " + elapsedTime);
var info = new FileInfo(stream.Name);
Console.WriteLine("Speed: {0:0.00} MB/s", info.Length / ts.TotalSeconds / 1024.0 / 1024.0);
同じことを行いますが、160kフロートの1次元配列を使用すると、同じ量のデータが最大179 MB/sでディスクにシリアル化されます。20倍以上高速です! を使用して2次元配列をシリアル化すると、BinaryFormatter
パフォーマンスが低下するのはなぜですか? メモリ内の2つのアレイの基本的なストレージは同一である必要があります。(安全でないネイティブpin_ptrを実行し、C ++ / CLIで2D配列との間でコピーを実行しました)。
ISerializable
ハックな解決策は、2D配列を1D配列に実装してmemcopy(unsafe / ptr pinning / block memcopy)を実行し、それと次元をシリアル化することです。私が検討しているもう1つのオプションは、への切り替えprotobuf-net
です。