14

Github Make BinaryFormatter faster · Issue #20569 · dotnet/runtime · GitHub

 3 years ago
source link: https://github.com/dotnet/runtime/issues/20569
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Contributor

Alois-xx commented on Mar 11, 2017

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.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK