反序列化文件中的数据。性能问题

问题描述 投票:4回答:7

我从数据库中读取了一个包含超过100万条记录的表。我需要3分钟才能在内存中填充对象。我想优化此过程,并使用二进制BinaryFormatter将此对象序列化为文件。它创建了一个1/2 GB大小的文件。我将此文件反序列化回内存对象后。这花了11分钟!

问题:为什么从数据库读取所有这些数据要比从文件读取所有这些数据要快得多?是否有可能以某种方式优化反序列化过程?

数据库在我测试的同一台机器上。其他进程此时都没有占用CPU时间。 CPU有4个内核,有40 GB内存。

编辑:反序列化的代码:

    using (FileStream fs = new FileStream(filename, FileMode.Open))
    {
        var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        var data = (MyType)bf.Deserialize(fs);
        ...
    }
.net optimization performance serialization
7个回答
5
投票

由于Binary Serializer的工作方式,它很慢。它将大量基于反射的元数据注入到二进制文件中。几年前我对一些相当大的结构进行了一些测试,发现XMLSerializer比二进制序列化器更小更快。去搞清楚!

在任何一种情况下,序列化都是通过反射来完成的,这很慢。您可以考虑自己的序列化机制。

我曾经创建了自己的二进制序列化机制(使用文件写/读),它的执行速度比XML序列化器快20倍,后者的执行速度比二进制序列化器快。它也明显更小。

你可能想考虑做那样的事情。


1
投票

http://www.codeproject.com/KB/cs/FastSerialization.aspx

这是我在我自己的项目中实现的一个很好的自定义序列化类,非常容易使用。会推荐。

显然比标准格式化程序快4倍,并且可以轻松访问内部结构意味着您可以编写自己的.NET4并行改进。


0
投票

我注意到.NET初始化XmlSerializers需要一段时间。因此,如果您不重用序列化程序对象,那么这样做可以显着加快该过程。


0
投票

我发现序列化是一个相当大的开销,我希望从文件反序列化这么多数据比从数据库中查询要花费更长的时间。您还要从磁盘上的文件中读取数据,这样也会很昂贵。如果您正在尝试缓存数据,最好查看一些内存选项。


0
投票

我同意Brian的帖子。如果编写自己的持久性逻辑,则可以消除反射调用的开销,并完全控制从磁盘加载数据的方式。您将不得不编写更多代码,但在这种情况下可能是优化的代价。


0
投票

你有没有描述过你的特定场景?

注释假设问题是反射,但我现在正在研究一个类似的场景(从文件到对象内存树的反序列化)以及似乎正在发生的事情是BinaryFormatter.Deserialize()似乎是逐个或小地读取字节块用于重新水合物体。

以下是我拥有的三个最独特的消费功能:

29%Microsoft.Win32.Win32Native :: ReadFile 22%Microsoft.Win32.Win32Native :: SetFilePointerWin32 12%Microsoft.Win32.Win32Native :: SetFilePointer

我想知道是否有办法告诉BinaryFormatter以块为单位读取ex。试过BufferedStream和MemoryStream,没有运气......


0
投票

自从我提出这个问题以来差不多9年了。在.NET二进制序列化程序中没有太大的改变,但我找到了另一个库来替换它。

这是一个名为Slim Serializer的东西,它是NFX库的一部分。这里有一些链接:

http://nfxlib.com/book/serialization/slim.html

http://developers-club.com/posts/257247/

https://github.com/agnicore/nfx

Nuget:https://www.nuget.org/packages/NFX/

性能:

这是300k复杂对象的基准,其中序列化为大约500MB的文件。

Bs  = .NET 4.5 Binary Serializer)
Nfx = Nfx slim serializer

Bs  serialization:   00:00:20.7391613 (606,791,842 bytes)
Nfx serialization:   00:00:06.7498946 (538,040,784 bytes)
Bs  deserialization: 00:03:29.8163338
Nfx deserialization: 00:00:02.7875492

附:从问题(11分钟)和这个答案(3.5分钟)的二进制串行器的性能差异我通过更好的硬件和可能的.NET版本的改进解释

© www.soinside.com 2019 - 2024. All rights reserved.