代码之家  ›  专栏  ›  技术社区  ›  Kamarey

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

  •  4
  • Kamarey  · 技术社区  · 15 年前

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

    编辑:用于反序列化的代码:

        using (FileStream fs = new FileStream(filename, FileMode.Open))
        {
            var bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            var data = (MyType)bf.Deserialize(fs);
            ...
        }
    
    7 回复  |  直到 15 年前
        1
  •  5
  •   Brian Genisio    15 年前

    由于二进制序列化程序的工作方式,它的速度非常慢。它将大量基于反射的元数据注入到二进制文件中。几年前,我对一些相当大的结构运行了一些测试,发现XMLSerializer比二进制序列化器更小、更快。想想看吧

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

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

        2
  •  1
  •   JaredBroad    15 年前

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

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

        3
  •  0
  •   Skrim    15 年前

    我注意到.NET初始化XmlSerializer需要相当长的时间。因此,如果您不重用序列化程序对象,那么这样做应该会显著加快该过程。

        4
  •  0
  •   Charlie Gevious    15 年前

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

        5
  •  0
  •   Andy Holt    15 年前

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

        6
  •  0
  •   Ariel    15 年前

    轮廓

    注释假定问题是反射,但我现在正在处理一个类似的场景(从文件到对象内存树的反序列化),似乎正在发生的是BinaryFormatter.Deserialize()似乎正在逐个读取字节或小块,以便重新水合对象。

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

    我想知道是否有一种方法可以告诉BinaryFormatter按块读取ex。尝试了BufferedStream和MemoryStream,但没有成功。。。

        7
  •  0
  •   Community CDub    4 年前

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

    它被称为Slim Serializer,是NFX库的一部分。以下是一些链接:

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

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

    https://github.com/agnicore/nfx

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

    性能:

    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版本中可能的改进进行了解释