Il modo più veloce per serializzare e deserializzare oggetti .NET


88

Sto cercando il modo più veloce per serializzare e deserializzare oggetti .NET. Ecco cosa ho finora:

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
Prestazioni o impronta di codice?
ulrichb

Mi stai chiedendo se ho bisogno di dati o codice sulle prestazioni?
aron

3
Chiede se, per "modo più veloce", intendi in termini di prestazioni o in termini di impronta del codice. BinaryFormatterè estremamente veloce in termini di codice e implementazione, ma una soluzione come quella di Marc sarà più veloce in un benchmark.
Cody Grey

ok, capisco, intendevo in termini di prestazioni ...
aron

Ci sono molti link là fuori. Uno di questi: blogs.msdn.com/b/youssefm/archive/2009/07/10/…
nawfal

Risposte:


58

Ecco il tuo modello (con inventato CTe TE) che utilizza protobuf-net (pur mantenendo la capacità di utilizzo XmlSerializer, che può essere utile, in particolare per la migrazione); Sottolineo umilmente (con molte prove se ne avete bisogno) che questo è il serializzatore generico più veloce (o sicuramente uno dei più veloci) in .NET.

Se hai bisogno di stringhe, codifica solo in base 64 il binario.

[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
Buongiorno Marc, adoro il lavoro sui buffer di protocollo che hai fatto e so che questo post è vecchio di quasi 5 anni, ma il netserializer citato in una risposta qui (Binoj) ha metriche che indicano che la tua implementazione non è la più veloce. È una dichiarazione / pubblicità equa o c'è un compromesso? grazie
Jeremy Thompson

ok vedo ora, NetSerialization funziona solo per la stessa versione in cui sto cercando la serializzazione tollerante alla versione
Jeremy Thompson

1
Chiunque pensi che sia veloce deve fumare qualcosa, potrebbe essere abbastanza veloce per molti casi e potrebbe essere più veloce di molti altri serializzati là fuori, ma in realtà è veloce, rispetto all'analisi manuale? Mio dio no.
BjarkeCK

I serializzatori @BjarkeCK sono intrinsecamente un po 'più coinvolti, poiché devono fare molte cose per evitare che le persone si sparino da sole (specialmente mentre iterano le versioni); la maggior parte delle persone non vuole passare la vita a eseguire il debug del codice di serializzazione, quindi: un buon serializzatore - sebbene indubbiamente più lento di un'implementazione manuale intollerante alla versione perfettamente implementata - è di solito un buon compromesso per la maggior parte delle persone
Marc Gravell

2
@BjarkeCK Sono fortemente in disaccordo; non è nemmeno lontanamente utile per la maggior parte delle persone. E poi: scrivere le nostre raccolte ogni giorno? No: fare queste cose anche abbastanza bene è difficile . Certo, se hai davvero bisogno dell'output più veloce: dovrai sporcarti le mani, ma per la maggior parte delle persone, farlo sarebbe davvero una brutta perdita di tempo. Nella migliore delle ipotesi ci sarebbero voluti molto più tempo. Più probabilmente, il loro codice sarebbe difettoso, inaffidabile e probabilmente più lento rispetto all'utilizzo delle librerie disponibili. La maggior parte delle persone dovrebbe concentrarsi su ciò di cui la propria app ha bisogno , non su questo minuto.
Marc Gravell

34

6
Non è velocità. Questa è lentezza. Dice "più piccolo è meglio" nell'articolo collegato.
Timur Nuriyasov

2
@TimurNuriyasov, questo è il tempo impiegato per eseguire l'operazione
Maxim

2
Quindi dici che il binario è il più lento? Non credo proprio! Immagino che si riferisca correttamente alla velocità, non al tempo.
Javid

2
Il binario è il più lento. Prova te stesso. Ma direi che è più semplice, in quanto non richiede alcuna risoluzione personalizzata per funzionare correttamente con oggetti polimorfici (interfacce, ecc.)
Kamarey

1
@Kamarey guarda il mio test qui sotto ... il binario è molto più veloce degli altri.
Jeremy Holovacs

20

Essendo interessato a questo, ho deciso di testare i metodi suggeriti con il test "mele a mele" più vicino possibile. Ho scritto un'app Console, con il seguente codice:

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);
            }
        }
    }
}

I risultati mi hanno sorpreso; erano coerenti se eseguiti più volte:

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.

Raccogliendo questi risultati, ho deciso di vedere se ProtoBuf o NetSerializer funzionavano meglio con oggetti più grandi. Ho modificato il conteggio della raccolta a 10.000 oggetti, ma ho aumentato la dimensione degli array a 1-10.000 invece di 1-100. I risultati sembravano ancora più definitivi:

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.

La mia conclusione, quindi, è: ci possono essere casi in cui ProtoBuf e NetSerializer sono adatti, ma in termini di prestazioni non elaborate per oggetti relativamente semplici almeno ... BinaryFormatter è significativamente più performante, almeno di un ordine di grandezza.

YMMV.


1
forse BinaryFormatter è solo molto veloce con gli array.
Behrooz

4
È possibile ... ma nelle condizioni menzionate, i risultati sono stati drammatici. La lezione qui potrebbe essere: non credere che un metodo sia il più performante in tutte le circostanze. Test e benchmarking illuminano sempre.
Jeremy Holovacs

In C ++ la serializzazione degli oggetti è circa 100 volte più veloce!
Mario M

Molto interessante! Tutti hanno affermato che il protobuf è il più veloce, ma questo mostra chiaramente che è dolorosamente lento. Ho aggiunto il mio BinaronSerializer al mix qui dotnetfiddle.net/gOqQ7p : è quasi il doppio più veloce di BinaryFormatter, che è già molto veloce con gli array.
Zach Saw

16

Protobuf è molto molto veloce.

Vedere http://code.google.com/p/protobuf-net/wiki/Performance per informazioni dettagliate sulle prestazioni di questo sistema e un'implementazione.


Ci sono degli svantaggi nell'utilizzo di Protobuf?
Robert Jeppesen

11
Devi annotare i tuoi oggetti. Protobuf non memorizza i nomi ei tipi di campo come fanno i serializzatori, ma li prende dai tipi effettivi. Questo è uno dei motivi per cui i file di destinazione sono molto più piccoli. La documentazione spiega tutto questo. Lo uso da un po 'di tempo e se hai bisogno di una rapida (de) serializzazione e di piccoli file di destinazione, protobuf è davvero la strada da percorrere.
Pieter van Ginkel

Qualche esempio di codice sorgente completo che utilizza Protobut in C # da aggiungere alla risposta?
Kiquenet

Non è così veloce ... In effetti, è piuttosto lento rispetto ai serializzatori molto molto molto molto veloci: dotnetfiddle.net/gOqQ7p
Zach Saw

@ZachSaw non è così veloce se hai a che fare solo con array di numeri interi (il tuo esempio), ma pochissime persone serializzano solo interi. Vedi i vantaggi in termini di velocità (o almeno lo faccio io), quando inizi a gestire tipi complessi annidati con molti membri.
matt.rothmeyer

15

Ancora un altro serializzatore là fuori che afferma di essere super veloce è netserializer .

I dati forniti sul loro sito mostrano prestazioni di 2x - 4x su protobuf , non l'ho provato da solo, ma se stai valutando varie opzioni, prova anche questo


3
Ho appena provato NetSerializer nella mia applicazione e funziona a meraviglia. Vale la pena provare.
Galen

netserializer non è adatto per serializzare oggetti "utente" in cui la libreria non sa con cosa iniziano i tipi, o ha anche la possibilità di forzare l'utente a contrassegnare i propri oggetti come serializzabili.
Zach Saw

6

Il serializzatore binario incluso con .net dovrebbe essere più veloce di XmlSerializer. O un altro serializzatore per protobuf, json, ...

Ma per alcuni di essi è necessario aggiungere attributi o un altro modo per aggiungere metadati. Ad esempio, ProtoBuf utilizza internamente ID di proprietà numerici e la mappatura deve essere in qualche modo conservata da un meccanismo diverso. Il controllo delle versioni non è banale con nessun serializzatore.


Sì, è davvero molto veloce e gestisce molti più casi / tipi rispetto a Xml.
leppie

1

Ho rimosso i bug nel codice sopra e ho ottenuto i seguenti risultati: Inoltre non sono sicuro dato come NetSerializer richieda di registrare i tipi che stai serializzando, che tipo di compatibilità o differenze di prestazioni che potrebbero potenzialmente fare.

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.

Codice modificato

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
A quali bug ti riferisci?
Jeremy Holovacs

0

Puoi provare Salar.Bois serializzatore che ha prestazioni decenti. Il suo focus è sulle dimensioni del carico utile, ma offre anche buone prestazioni.

Ci sono benchmark nella pagina Github se desideri vedere e confrontare i risultati da solo.

https://github.com/salarcode/Bois


0

Mi sono preso la libertà di inserire le tue classi nel generatore CGbR .Perché è in una fase iniziale non supporta DateTime ancora , quindi l'ho semplicemente sostituito con long. Il codice di serializzazione generato ha questo aspetto:

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;
}

Ho creato un elenco di oggetti di esempio come questo:

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);
}

Risultati sulla mia macchina in Releasebuild:

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

Taglia: 149000 byte

Tempo: 2,059 ms 3,13 ms

Modifica: a partire da CGbR 0.4.3 il serializzatore binario supporta DateTime. Purtroppo il DateTime.ToBinarymetodo è incredibilmente lento. Lo sostituirò presto con qualcosa di più veloce.

Modifica2: quando si utilizza UTC DateTimeinvocando ToUniversalTime()la performance viene ripristinata e il clock inizia a 1.669 ms .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.