我正在使用BinaryFormatter
序列化一个相当简单的多维浮点数组,尽管我怀疑任何原始类型都会出现问题。我的多维数组包含 10000x16 个浮点数(160k),并且在我的 PC 上以 ~8 MB/s 的速度进行序列化(60 秒基准写入 ~500 MB 到 SSD 驱动器)。代码:
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 浮点数的一维数组,相同数量的数据以 ~179 MB/s 的速度序列化到磁盘。速度提高 20 倍以上! 为什么使用序列化二维数组的BinaryFormatter
性能如此糟糕? 内存中两个数组的底层存储应该是相同的。(我已经完成了不安全的本机 pin_ptr 并在 C++/CLI 中复制到二维数组和从二维数组复制)。
一个骇人听闻的解决方案是实现ISerializable
并执行 memcopy(不安全/ptr pinning/block memcopy)将 2D 数组转换为 1D 数组并将其和维度序列化。我正在考虑的另一个选择是切换到protobuf-net
.