Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.NET中使用BinaryFormatter序列化多维数组时出现性能问题_.net_Performance_Serialization_Multidimensional Array_Binaryformatter - Fatal编程技术网

在.NET中使用BinaryFormatter序列化多维数组时出现性能问题

在.NET中使用BinaryFormatter序列化多维数组时出现性能问题,.net,performance,serialization,multidimensional-array,binaryformatter,.net,Performance,Serialization,Multidimensional Array,Binaryformatter,我正在使用BinaryFormatter序列化一个相当简单的多维浮点数组,尽管我怀疑任何基元类型都会出现问题。我的多维阵列包含10000x16浮点(160k),在我的PC上串行化运行速度约为8 MB/s(60秒基准测试将约500 MB写入SSD驱动器)。代码: 秒表秒表=新秒表(); 浮动[,]数据=新浮动[10000,16];//160000个浮点数的二维数组。 //或 浮点[]数据=新浮点[10000*16];//160000个浮点数的一维数组。 var formatter=新的二进制格式化

我正在使用
BinaryFormatter
序列化一个相当简单的多维浮点数组,尽管我怀疑任何基元类型都会出现问题。我的多维阵列包含10000x16浮点(160k),在我的PC上串行化运行速度约为8 MB/s(60秒基准测试将约500 MB写入SSD驱动器)。代码:

秒表秒表=新秒表();
浮动[,]数据=新浮动[10000,16];//160000个浮点数的二维数组。
//或
浮点[]数据=新浮点[10000*16];//160000个浮点数的一维数组。
var formatter=新的二进制格式化程序();
var stream=new FileStream(“C:\\Temp\\test\u serialization.data”,FileMode.Create,FileAccess.Write);
//将阵列序列化到磁盘1000次。
秒表复位();
秒表。开始();
对于(int i=0;i<1000;i++)
{
序列化(流、数据);
}
stream.Close();
秒表;
TimeSpan ts=秒表。已用时间;
//格式化并显示TimeSpan值。
string elapsedTime=string.Format(“{0:00}:{1:00}:{2:00}.{3:000}”,
时,分,秒,
ts毫秒);
Console.WriteLine(“运行时”+elapsedTime);
var info=新文件信息(stream.Name);
WriteLine(“速度:{0:0.00}MB/s”,info.Length/ts.TotalSeconds/1024.0/1024.0);
做同样的事情,但使用160k浮点的一维数组,相同数量的数据以约179MB/s的速度序列化到磁盘。快20倍以上为什么使用
BinaryFormatter
序列化二维数组的性能如此差?
内存中两个数组的底层存储应该是相同的。(我已经在C++/CLI中完成了不安全的本机pin_ptr和向2D数组复制以及从2D数组复制)


黑客的解决方案是实现
ISerializable
,并将2D数组进行memcopy(不安全/ptr钉扎/block memcopy)操作,将其转换为1D数组,然后将其和维度序列化。我正在考虑的另一个选择是切换到protobuf net

无需放弃数据结构或复制值,您可以使用以下代码实现相同的性能:

            fixed (float* ptr = data)
            {
                byte* arr = (byte*)ptr;
                int size = sizeof(float);

                for (int j = 0; j < data.Length * size; j++)
                {
                    stream.WriteByte(arr[j]);
                }
            }
固定(浮动*ptr=数据)
{
字节*arr=(字节*)ptr;
int size=sizeof(float);
对于(int j=0;j
基本上,您是自己编写输出流的,正如您所说的,您只是将float[]用作byte[],因为内存结构是相同的

反序列化是相同的,您可以使用StreamReader来读取浮点值,也可以使用不安全的方法将数据加载到内存中

如果您有这样的基本需求,我强烈反对使用protobuf.net。开发速度减慢,而且只基于一个人,因此风险很大(当我试图帮助解决性能问题时,他甚至懒得看我提出的更改)。
然而,如果您想序列化复杂的数据结构,二进制序列化不会比protobuf慢很多,尽管后者在.NET平台上没有得到官方支持(Google发布了Java、Python和C++的代码)。

它在反射上花费了太多时间。数组很麻烦,因为它们在.NET中是协变的。您可以使用锯齿阵列加快速度。
            fixed (float* ptr = data)
            {
                byte* arr = (byte*)ptr;
                int size = sizeof(float);

                for (int j = 0; j < data.Length * size; j++)
                {
                    stream.WriteByte(arr[j]);
                }
            }