Skip to content

Make BinaryFormatter faster #20569

Closed
dotnet/corefx
#17949
@Alois-xx

Description

@Alois-xx

When BinaryFormatter encounters a larger object list it gets quadratic deserialization times due to the linear search in

>	ConsoleApp2.dll!System.Runtime.Serialization.ObjectManager.FindObjectHolder(long objectID) Line 68	C#
 	ConsoleApp2.dll!System.Runtime.Serialization.ObjectManager.FindOrCreateObjectHolder(long objectID) Line 81	C#
 	ConsoleApp2.dll!System.Runtime.Serialization.ObjectManager.RegisterFixup(System.Runtime.Serialization.FixupHolder fixup, long objectToBeFixed, long objectRequired) Line 888	C#
 	ConsoleApp2.dll!System.Runtime.Serialization.ObjectManager.RecordArrayElementFixup(long arrayToBeFixed, int[] indices, long objectRequired) Line 966	C#

Sample

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApp2
{
    [Serializable]
    class Book
    {
        public string Name;
        public string Id;
    }

    class Program
    {
        static void Main(string[] args)
        {
            var formatter = new BinaryFormatter();
            List<Book> books = new List<Book>();
            var mem = new MemoryStream();
            for(int i=0;i<500*1000;i++)
            {
                books.Add(new Book { Id = i.ToString() });
            }

            var sw = Stopwatch.StartNew();
            formatter.Serialize(mem, books);
            sw.Stop();
            Console.WriteLine($"Serialization time {sw.Elapsed.TotalSeconds:F2}s");
            mem.Position = 0;
            sw = Stopwatch.StartNew();
            List<Book> booksDeser = (List<Book>)formatter.Deserialize(mem);
            sw.Stop();
            Console.WriteLine($"Deserialization {sw.Elapsed.TotalSeconds:F2}s");
        }
    }
}

Serialization time 2.31s
Deserialization 21.16s

This caused some unexpected "slowdowns" in production code when "real" big objects (e.g. 20 - 100 MB) object graphs are deserialized. Deserialization times of 10 minutes are not uncommon due to this. It would be great if this ugly thing gets cleaned up in .NET Core.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.RuntimeenhancementProduct code improvement that does NOT require public API changes/additionstenet-performancePerformance related issue

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions