Найшвидший спосіб серіалізації та десеріалізації .NET-об'єктів


87

Я шукаю найшвидший спосіб серіалізації та десеріалізації об'єктів .NET. Ось те, що я маю на сьогодні:

public class TD
{
    public List<CT> CTs { get; set; }
    public List<TE> TEs { get; set; }
    public string Code { get; set; }
    public string Message { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public static string Serialize(List<TD> tData)
    {
        var serializer = new XmlSerializer(typeof(List<TD>));

        TextWriter writer = new StringWriter();
        serializer.Serialize(writer, tData);

        return writer.ToString();
    }

    public static List<TD> Deserialize(string tData)
    {
        var serializer = new XmlSerializer(typeof(List<TD>));

        TextReader reader = new StringReader(tData);

        return (List<TD>)serializer.Deserialize(reader);
    }        
}

2
Продуктивність або кодовий відбиток?
ulrichb

Ви запитуєте мене, чи потрібні мені дані про ефективність чи код?
aron

3
Він запитує, чи під "найшвидшим способом" ви маєте на увазі терміни продуктивності чи терміни коду. BinaryFormatterє надзвичайно швидким з точки зору коду та реалізації, але таке рішення, як рішення Марка, буде працювати швидше у тесті.
Коді Грей

гаразд, розумію, я мав на увазі показники продуктивності ...
aron

Там багато посилань. Одне з таких: blogs.msdn.com/b/youssefm/archive/2009/07/10/…
nawfal

Відповіді:


57

Ось ваша модель (із винайденою CTта TE) з використанням protobuf-net (при цьому зберігаючи можливість використання XmlSerializer, що може бути корисним - зокрема, для міграції); Я смиренно підкорятися (з великою кількістю доказів , якщо вам це потрібно) , що є найшвидшим (або , звичайно , один з найшвидших) серіалізатор загального призначення в .NET.

Якщо вам потрібні рядки, просто base-64 закодуйте двійковий файл.

[XmlType]
public class CT {
    [XmlElement(Order = 1)]
    public int Foo { get; set; }
}
[XmlType]
public class TE {
    [XmlElement(Order = 1)]
    public int Bar { get; set; }
}
[XmlType]
public class TD {
    [XmlElement(Order=1)]
    public List<CT> CTs { get; set; }
    [XmlElement(Order=2)]
    public List<TE> TEs { get; set; }
    [XmlElement(Order = 3)]
    public string Code { get; set; }
    [XmlElement(Order = 4)]
    public string Message { get; set; }
    [XmlElement(Order = 5)]
    public DateTime StartDate { get; set; }
    [XmlElement(Order = 6)]
    public DateTime EndDate { get; set; }

    public static byte[] Serialize(List<TD> tData) {
        using (var ms = new MemoryStream()) {
            ProtoBuf.Serializer.Serialize(ms, tData);
            return ms.ToArray();
        }            
    }

    public static List<TD> Deserialize(byte[] tData) {
        using (var ms = new MemoryStream(tData)) {
            return ProtoBuf.Serializer.Deserialize<List<TD>>(ms);
        }
    }
}

2
G'day Marc, люблю роботу з буферами протоколів, яку ви зробили, і я знаю, що цій публікації майже 5 років, але netserializer, наведений у відповіді тут (Binoj), має показники, що вказують, що ваша реалізація не найшвидша. Це чесна заява / реклама чи є компроміс? подяка
Джеремі Томпсон

Гаразд, зараз я бачу, що NetSerialization працює лише для тієї самої версії, де, як я шукаю, толерантну серіалізацію версій
Джеремі Томпсон,

1
Той, хто вважає, що це швидко, повинен щось курити, це може бути досить швидко для багатьох випадків, і це може бути швидше, ніж багато інших серіалів, але це насправді швидко, порівняно з синтаксичним розбором вручну? Боже мій ні.
BjarkeCK

Серіалізатори @BjarkeCK за своєю суттю трохи більше беруть участь, оскільки їм потрібно зробити багато речей, щоб люди не стріляли собі ногами (особливо, оскільки вони повторюють версії); більшість людей не хочуть витрачати своє життя на налагодження коду серіалізації, тому: хороший серіалізатор - хоча, безсумнівно, повільніший, ніж ідеально реалізована ручна реалізація з нетерпимими версіями - зазвичай є хорошим компромісом для більшості людей
Марк Гравелл

1
@BjarkeCK Я категорично не згоден; це навіть далеко не корисно для більшості людей. Що далі - щодня писати власні колекції? Ні: робити ці речі навіть досить добре - важко . Звичайно, якщо вам насправді потрібен найшвидший результат: вам доведеться забруднити руки - але для більшості людей це робити буде дійсно поганою втратою свого часу. КРАЩО це зайняло б у них набагато більше часу. Швидше за все, їх код буде помилковим, ненадійним і, можливо, повільнішим, ніж використання наявних бібліотек. Більшість людей повинні концентруватися на тому, що потрібно їх додатку , а не на цій хвилині.
Марк Гравелл

33

Comprehansive порівняння diffreent форматів , зроблених мною в цьому пост- https://maxondev.com/serialization-performance-comparison-c-net-formats-frameworks-xmldatacontractserializer-xmlserializer-binaryformatter-json-newtonsoft-servicestack-text/

Лише один зразок з пост- введіть тут опис зображення


5
Це не швидкість. Це повільність. У цій статті сказано: "чим менше, тим краще".
Тимур Нуріясов

2
@TimurNuriyasov, ось час зайняв операцію
Максим

2
Отже, ви кажете, що двійковий файл - найповільніший? Я не думаю! Думаю, це правильно стосується швидкості, а не часу.
Джавід,

2
Бінарний - це найповільніший. Спробуйте самі. Але я б сказав, що це найпростіше, оскільки для правильної роботи з поліморфними об'єктами (інтерфейси тощо) не потрібні спеціальні матеріали, що дозволяють вирішувати проблеми
Камарей

1
@Kamarey подивіться на мій тест нижче ... двійковий файл набагато швидший за інші.
Jeremy Holovacs

19

Маючи інтерес до цього, я вирішив перевірити запропоновані методи за допомогою найближчого тесту "яблука до яблук", який я міг. Я написав консольний додаток із таким кодом:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace SerializationTests
{
    class Program
    {
        static void Main(string[] args)
        {
            var count = 100000;
            var rnd = new Random(DateTime.UtcNow.GetHashCode());
            Console.WriteLine("Generating {0} arrays of data...", count);
            var arrays = new List<int[]>();
            for (int i = 0; i < count; i++)
            {
                var elements = rnd.Next(1, 100);
                var array = new int[elements];
                for (int j = 0; j < elements; j++)
                {
                    array[j] = rnd.Next();
                }   
                arrays.Add(array);
            }
            Console.WriteLine("Test data generated.");
            var stopWatch = new Stopwatch();

            Console.WriteLine("Testing BinarySerializer...");
            var binarySerializer = new BinarySerializer();
            var binarySerialized = new List<byte[]>();
            var binaryDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var array in arrays)
            {
                binarySerialized.Add(binarySerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("BinaryFormatter: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in binarySerialized)
            {
                binaryDeserialized.Add(binarySerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("BinaryFormatter: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);


            Console.WriteLine();
            Console.WriteLine("Testing ProtoBuf serializer...");
            var protobufSerializer = new ProtoBufSerializer();
            var protobufSerialized = new List<byte[]>();
            var protobufDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var array in arrays)
            {
                protobufSerialized.Add(protobufSerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("ProtoBuf: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in protobufSerialized)
            {
                protobufDeserialized.Add(protobufSerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("ProtoBuf: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            Console.WriteLine();
            Console.WriteLine("Testing NetSerializer serializer...");
            var netSerializerSerializer = new ProtoBufSerializer();
            var netSerializerSerialized = new List<byte[]>();
            var netSerializerDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var array in arrays)
            {
                netSerializerSerialized.Add(netSerializerSerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("NetSerializer: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in netSerializerSerialized)
            {
                netSerializerDeserialized.Add(netSerializerSerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("NetSerializer: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            Console.WriteLine("Press any key to end.");
            Console.ReadKey();
        }

        public class BinarySerializer
        {
            private static readonly BinaryFormatter Formatter = new BinaryFormatter();

            public byte[] Serialize(object toSerialize)
            {
                using (var stream = new MemoryStream())
                {
                    Formatter.Serialize(stream, toSerialize);
                    return stream.ToArray();
                }
            }

            public T Deserialize<T>(byte[] serialized)
            {
                using (var stream = new MemoryStream(serialized))
                {
                    var result = (T)Formatter.Deserialize(stream);
                    return result;
                }
            }
        }

        public class ProtoBufSerializer
        {
            public byte[] Serialize(object toSerialize)
            {
                using (var stream = new MemoryStream())
                {
                    ProtoBuf.Serializer.Serialize(stream, toSerialize);
                    return stream.ToArray();
                }
            }

            public T Deserialize<T>(byte[] serialized)
            {
                using (var stream = new MemoryStream(serialized))
                {
                    var result = ProtoBuf.Serializer.Deserialize<T>(stream);
                    return result;
                }
            }
        }

        public class NetSerializer
        {
            private static readonly NetSerializer Serializer = new NetSerializer();
            public byte[] Serialize(object toSerialize)
            {
                return Serializer.Serialize(toSerialize);
            }

            public T Deserialize<T>(byte[] serialized)
            {
                return Serializer.Deserialize<T>(serialized);
            }
        }
    }
}

Результати мене здивували; вони були послідовними при запуску кілька разів:

Generating 100000 arrays of data...
Test data generated.
Testing BinarySerializer...
BinaryFormatter: Serializing took 336.8392ms.
BinaryFormatter: Deserializing took 208.7527ms.

Testing ProtoBuf serializer...
ProtoBuf: Serializing took 2284.3827ms.
ProtoBuf: Deserializing took 2201.8072ms.

Testing NetSerializer serializer...
NetSerializer: Serializing took 2139.5424ms.
NetSerializer: Deserializing took 2113.7296ms.
Press any key to end.

Зібравши ці результати, я вирішив перевірити, чи ефективніше ProtoBuf чи NetSerializer з більшими об’єктами. Я змінив кількість колекцій до 10 000 об'єктів, але збільшив розмір масивів до 1-10 000 замість 1-100. Результати видалися ще більш визначеними:

Generating 10000 arrays of data...
Test data generated.
Testing BinarySerializer...
BinaryFormatter: Serializing took 285.8356ms.
BinaryFormatter: Deserializing took 206.0906ms.

Testing ProtoBuf serializer...
ProtoBuf: Serializing took 10693.3848ms.
ProtoBuf: Deserializing took 5988.5993ms.

Testing NetSerializer serializer...
NetSerializer: Serializing took 9017.5785ms.
NetSerializer: Deserializing took 5978.7203ms.
Press any key to end.

Отже, мій висновок такий: можуть бути випадки, коли ProtoBuf та NetSerializer добре підходять, але з точки зору вихідної продуктивності принаймні відносно простих об’єктів ... BinaryFormatter значно ефективніший, принаймні на порядок.

YMMV.


1
можливо BinaryFormatter просто дуже швидко працює з масивами.
Behrooz

4
Це можливо ... але за згаданих умов результати були вражаючими. Урок тут може бути просто, не вірте, що один із методів є найефективнішим за будь-яких обставин. Тестування та порівняльний аналіз завжди прояснює.
Джеремі Головац

У С ++ серіалізація об'єктів відбувається приблизно в 100 разів швидше!
Маріо М

Дуже цікаво! Усі стверджували, що protobuf є найшвидшим, але це однозначно показує, що він болісно повільний. Я додав свій BinaronSerializer до міксу тут dotnetfiddle.net/gOqQ7p - це майже вдвічі швидше, ніж BinaryFormatter, який вже справді швидкий з масивами.
Zach Saw

16

Protobuf дуже швидко працює.

Дивіться http://code.google.com/p/protobuf-net/wiki/Performance, щоб отримати детальну інформацію щодо продуктивності цієї системи та реалізації.


Чи є недоліки у використанні Protobuf?
Роберт Джеппесен,

11
Ви повинні анотувати свої об’єкти. Protobuf не зберігає імена полів і типи, як це роблять серіалізатори, а бере їх із ваших фактичних типів. Це одна з причин, чому цільові файли набагато менші. Все це пояснює документація. Я використовую його вже деякий час, і якщо вам потрібна швидка (де) серіалізація та невеликі цільові файли, протобуф - це справді шлях.
Пітер ван Гінкель,

Будь-який повний зразок вихідного коду з використанням протобуту в C # для додавання до відповіді?
Kiquenet

Це не так швидко ... Насправді, це досить повільно в порівнянні з дуже дуже дуже дуже швидкими серіалізаторами: dotnetfiddle.net/gOqQ7p
Zach Saw

@ZachSaw це не так швидко, якщо ви просто маєте справу з масивами цілих чисел (ваш приклад), але дуже мало людей лише серіалізують цілі числа. Ви бачите переваги швидкості (або принаймні я), коли ви починаєте мати справу з вкладеними складними типами з великою кількістю членів.
matt.rothmeyer

15

Ще один серіалізатор, який стверджує, що він дуже швидкий, - це netserializer .

Дані, наведені на їх веб-сайті, показують продуктивність у 2 - 4 рази за протобуф , я не пробував цього сам, але якщо ви оцінюєте різні варіанти, спробуйте і це


3
Я щойно спробував NetSerializer у своєму додатку, і він творить чудеса. Варто спробувати.
Гален

netserializer не підходить для серіалізації "користувацьких" об'єктів, коли бібліотека не знає, з яких типів починати, або навіть має можливість примусити користувача позначати свої об'єкти як серіалізуються.
Zach Saw

6

Бінарний серіалізатор, що входить до .net, повинен бути швидшим, ніж XmlSerializer. Або інший серіалізатор для protobuf, json, ...

Але для деяких з них вам потрібно додати атрибути або іншим способом додати метадані. Наприклад, ProtoBuf використовує числові ідентифікатори властивостей всередині, і відображення потрібно якось зберегти за допомогою іншого механізму. Версія не є тривіальною з будь-яким серіалізатором.


Так, насправді це дуже швидко, і він обробляє набагато більше випадків / типів, ніж Xml.
леппі

1

Я видалив помилки у наведеному вище коді та отримав результати нижче: Також я не впевнений, враховуючи, як NetSerializer вимагає від вас реєструвати типи, які ви серіалізуєте, яку різницю у сумісності чи продуктивності потенційно можуть зробити.

Generating 100000 arrays of data...
Test data generated.
Testing BinarySerializer...
BinaryFormatter: Serializing took 508.9773ms.
BinaryFormatter: Deserializing took 371.8499ms.

Testing ProtoBuf serializer...
ProtoBuf: Serializing took 3280.9185ms.
ProtoBuf: Deserializing took 3190.7899ms.

Testing NetSerializer serializer...
NetSerializer: Serializing took 427.1241ms.
NetSerializer: Deserializing took 78.954ms.
Press any key to end.

Модифікований код

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;

namespace SerializationTests
{
    class Program
    {
        static void Main(string[] args)
        {
            var count = 100000;
            var rnd = new Random((int)DateTime.UtcNow.Ticks & 0xFF);
            Console.WriteLine("Generating {0} arrays of data...", count);
            var arrays = new List<int[]>();
            for (int i = 0; i < count; i++)
            {
                var elements = rnd.Next(1, 100);
                var array = new int[elements];
                for (int j = 0; j < elements; j++)
                {
                    array[j] = rnd.Next();
                }
                arrays.Add(array);
            }
            Console.WriteLine("Test data generated.");
            var stopWatch = new Stopwatch();

            Console.WriteLine("Testing BinarySerializer...");
            var binarySerializer = new BinarySerializer();
            var binarySerialized = new List<byte[]>();
            var binaryDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var array in arrays)
            {
                binarySerialized.Add(binarySerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("BinaryFormatter: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in binarySerialized)
            {
                binaryDeserialized.Add(binarySerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("BinaryFormatter: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);


            Console.WriteLine();
            Console.WriteLine("Testing ProtoBuf serializer...");
            var protobufSerializer = new ProtoBufSerializer();
            var protobufSerialized = new List<byte[]>();
            var protobufDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var array in arrays)
            {
                protobufSerialized.Add(protobufSerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("ProtoBuf: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in protobufSerialized)
            {
                protobufDeserialized.Add(protobufSerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("ProtoBuf: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            Console.WriteLine();
            Console.WriteLine("Testing NetSerializer serializer...");
            var netSerializerSerialized = new List<byte[]>();
            var netSerializerDeserialized = new List<int[]>();

            stopWatch.Reset();
            stopWatch.Start();
            var netSerializerSerializer = new NS();
            foreach (var array in arrays)
            {
                netSerializerSerialized.Add(netSerializerSerializer.Serialize(array));
            }
            stopWatch.Stop();
            Console.WriteLine("NetSerializer: Serializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            stopWatch.Reset();
            stopWatch.Start();
            foreach (var serialized in netSerializerSerialized)
            {
                netSerializerDeserialized.Add(netSerializerSerializer.Deserialize<int[]>(serialized));
            }
            stopWatch.Stop();
            Console.WriteLine("NetSerializer: Deserializing took {0}ms.", stopWatch.Elapsed.TotalMilliseconds);

            Console.WriteLine("Press any key to end.");
            Console.ReadKey();
        }

        public class BinarySerializer
        {
            private static readonly BinaryFormatter Formatter = new BinaryFormatter();

            public byte[] Serialize(object toSerialize)
            {
                using (var stream = new MemoryStream())
                {
                    Formatter.Serialize(stream, toSerialize);
                    return stream.ToArray();
                }
            }

            public T Deserialize<T>(byte[] serialized)
            {
                using (var stream = new MemoryStream(serialized))
                {
                    var result = (T)Formatter.Deserialize(stream);
                    return result;
                }
            }
        }

        public class ProtoBufSerializer
        {
            public byte[] Serialize(object toSerialize)
            {
                using (var stream = new MemoryStream())
                {
                    ProtoBuf.Serializer.Serialize(stream, toSerialize);
                    return stream.ToArray();
                }
            }

            public T Deserialize<T>(byte[] serialized)
            {
                using (var stream = new MemoryStream(serialized))
                {
                    var result = ProtoBuf.Serializer.Deserialize<T>(stream);
                    return result;
                }
            }
        }

        public class NS
        {
            NetSerializer.Serializer Serializer = new NetSerializer.Serializer(new Type[] { typeof(int), typeof(int[]) });

            public byte[] Serialize(object toSerialize)
            {
                using (var stream = new MemoryStream())
                {
                    Serializer.Serialize(stream, toSerialize);
                    return stream.ToArray();
                }
            }

            public T Deserialize<T>(byte[] serialized)
            {
                using (var stream = new MemoryStream(serialized))
                {
                    Serializer.Deserialize(stream, out var result);
                    return (T)result;
                }
            }
        }
    }
}

1
Про які помилки ви маєте на увазі?
Джеремі Головац

0

Ви можете спробувати серіалізатор Salar.Bois, який має гідну продуктивність. Його основна увага приділяється розміру корисного навантаження, але вона також забезпечує хорошу продуктивність.

На сторінці Github є орієнтири, якщо ви хочете побачити та порівняти результати самостійно.

https://github.com/salarcode/Bois


0

Я взяв на себе можливість подавати ваші класи в генератор CGbR .Оскільки він на ранній стадії ще не підтримується DateTime, тому я просто замінив його на long. Створений код серіалізації виглядає так:

public int Size
{
    get 
    { 
        var size = 24;
        // Add size for collections and strings
        size += Cts == null ? 0 : Cts.Count * 4;
        size += Tes == null ? 0 : Tes.Count * 4;
        size += Code == null ? 0 : Code.Length;
        size += Message == null ? 0 : Message.Length;

        return size;              
    }
}

public byte[] ToBytes(byte[] bytes, ref int index)
{
    if (index + Size > bytes.Length)
        throw new ArgumentOutOfRangeException("index", "Object does not fit in array");

    // Convert Cts
    // Two bytes length information for each dimension
    GeneratorByteConverter.Include((ushort)(Cts == null ? 0 : Cts.Count), bytes, ref index);
    if (Cts != null)
    {
        for(var i = 0; i < Cts.Count; i++)
        {
            var value = Cts[i];
            value.ToBytes(bytes, ref index);
        }
    }
    // Convert Tes
    // Two bytes length information for each dimension
    GeneratorByteConverter.Include((ushort)(Tes == null ? 0 : Tes.Count), bytes, ref index);
    if (Tes != null)
    {
        for(var i = 0; i < Tes.Count; i++)
        {
            var value = Tes[i];
            value.ToBytes(bytes, ref index);
        }
    }
    // Convert Code
    GeneratorByteConverter.Include(Code, bytes, ref index);
    // Convert Message
    GeneratorByteConverter.Include(Message, bytes, ref index);
    // Convert StartDate
    GeneratorByteConverter.Include(StartDate.ToBinary(), bytes, ref index);
    // Convert EndDate
    GeneratorByteConverter.Include(EndDate.ToBinary(), bytes, ref index);
    return bytes;
}

public Td FromBytes(byte[] bytes, ref int index)
{
    // Read Cts
    var ctsLength = GeneratorByteConverter.ToUInt16(bytes, ref index);
    var tempCts = new List<Ct>(ctsLength);
    for (var i = 0; i < ctsLength; i++)
    {
        var value = new Ct().FromBytes(bytes, ref index);
        tempCts.Add(value);
    }
    Cts = tempCts;
    // Read Tes
    var tesLength = GeneratorByteConverter.ToUInt16(bytes, ref index);
    var tempTes = new List<Te>(tesLength);
    for (var i = 0; i < tesLength; i++)
    {
        var value = new Te().FromBytes(bytes, ref index);
        tempTes.Add(value);
    }
    Tes = tempTes;
    // Read Code
    Code = GeneratorByteConverter.GetString(bytes, ref index);
    // Read Message
    Message = GeneratorByteConverter.GetString(bytes, ref index);
    // Read StartDate
    StartDate = DateTime.FromBinary(GeneratorByteConverter.ToInt64(bytes, ref index));
    // Read EndDate
    EndDate = DateTime.FromBinary(GeneratorByteConverter.ToInt64(bytes, ref index));

    return this;
}

Я створив список зразків таких об'єктів:

var objects = new List<Td>();
for (int i = 0; i < 1000; i++)
{
    var obj = new Td
    {
        Message = "Hello my friend",
        Code = "Some code that can be put here",
        StartDate = DateTime.Now.AddDays(-7),
        EndDate = DateTime.Now.AddDays(2),
        Cts = new List<Ct>(),
        Tes = new List<Te>()
    };
    for (int j = 0; j < 10; j++)
    {
        obj.Cts.Add(new Ct { Foo = i * j });
        obj.Tes.Add(new Te { Bar = i + j });
    }
    objects.Add(obj);
}

Результати на моїй машині у Releaseзбірці:

var watch = new Stopwatch();
watch.Start();
var bytes = BinarySerializer.SerializeMany(objects);
watch.Stop();

Розмір: 149000 байт

Час: 2,059ms 3,13 мс

Редагувати: починаючи з CGbR 0.4.3, двійковий серіалізатор підтримує DateTime. На жаль, DateTime.ToBinaryметод шалено повільний. Незабаром я заміню його на швидше.

Edit2: При використанні UTC DateTimeза допомогою виклику ToUniversalTime()продуктивність відновлюється і працює на рівні 1,669 мс .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.