如何提高反序列化速度?

7

使用BinaryFormatter进行序列化/反序列化,生成的序列化文件大小约为80MB。反序列化需要几分钟时间。我该如何改进呢?以下是反序列化代码:

    public static Universe DeserializeFromFile(string filepath)
    {
        Universe universe = null;

        FileStream fs = new FileStream(filepath, FileMode.Open);

        BinaryFormatter bf = new BinaryFormatter();
        try
        {
            universe = (Universe)bf.Deserialize(fs);
        }
        catch (SerializationException e)
        {
            Console.WriteLine("Failed to deserialize. Reason: " + e.Message);
            throw;
        }
        finally
        {
            fs.Close();
        }

        return universe;
    }

也许在反序列化之前将所有内容读入内存,或者使用其他序列化技术会更好?
6个回答

2

我知道这是一个老问题,但偶然发现了一种可以显著提高反序列化速度的解决方案。如果你有大量数据集,这将非常有用。

将目标框架升级到4.7.1+并在你的app.config中启用以下开关。

<runtime>
    <!-- Use this switch to make BinaryFormatter fast with large object graphs starting with .NET 4.7.2 -->
    <AppContextSwitchOverrides value="Switch.System.Runtime.Serialization.UseNewMaxArraySize=true" />
</runtime>

来源: BinaryFormatter AppContextSwitchOverrides


1
在我的情况下,这会减慢序列化速度。 - Jawad Sabir
1
我的应用程序运行得非常好,谢谢! - bazza

2
尝试使用 UnsafeDeserialize。据说它可以提高速度。

不安全的反序列化 460138毫秒,正常反序列化只需要459967毫秒。也就是说,正常反序列化实际上更快!我使用UnsafeDeserialize将标题设置为null,这可能是原因吗? - Carlsberg

0

0

尝试先将文件一次性读入内存流中,然后使用内存流进行反序列化。


3
如果这样做能使情况变得更好而不是更糟,那么序列化格式就很糟糕。为什么要先进行一个I/O绑定的任务,然后再进行一个CPU绑定的任务,而不是交替进行两个任务呢? - hobbs

0

数据有多复杂?如果它是一个对象树(而不是完整的图形),那么尝试使用protobuf-net可能会得到一些有趣的结果。它通常很容易适配现有的类,并且通常比较小、快速和不易出错(您可以更改对象模型而不破坏数据)。

声明:我是作者,所以可能有偏见——但它真的不太糟糕……我很乐意花一些时间帮助您尝试它。

*=在合理范围内


-1

在Universe类中实现ISerializable接口


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接