.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 2010

성능 데이터 나 코드가 필요한가요?
aron 2010

3
그는 "가장 빠른 방법"이 성능 측면에서 또는 코드 풋 프린트 측면에서 의미하는지 묻고 있습니다. BinaryFormatter코드 및 구현 측면에서 매우 빠르지 만 Marc와 같은 솔루션은 벤치 마크에서 더 빠르게 수행됩니다.
Cody Gray

좋아요,
알겠습니다.

거기에 많은 링크가 있습니다. 그 중 하나 : blogs.msdn.com/b/youssefm/archive/2009/07/10/...
nawfal

답변:


57

다음은 protobuf-net을 사용하는 모델 ( CTTE)입니다 ( 특히 마이그레이션에 유용 할 수 있는를 사용 하는 기능을 유지함 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)에는 구현이 가장 빠르지 않음을 나타내는 메트릭이 있습니다. 공정한 진술 / 광고입니까, 아니면 상충 관계가 있습니까? 감사합니다
Jeremy Thompson

좋아, 이제 NetSerialization은 버전 허용 직렬화를 찾는 것과 동일한 버전에서만 작동합니다
Jeremy Thompson

1
이것이 빠르다고 생각하는 사람은 담배를 피워야합니다. 많은 경우에 충분히 빠를 수 있으며 다른 많은 직렬화보다 빠를 수 있지만 수동으로 파싱하는 것과 비교할 때 실제로 빠릅니다. 맙소사.
BjarkeCK

@BjarkeCK 시리얼 라이저는 사람들이 자신의 발을 쏘는 것을 막기 위해 많은 일을해야하기 때문에 (특히 반복 버전에서) 본질적으로 조금 더 복잡합니다. 대부분의 사람들은 그래서, 직렬화 코드를 디버깅 자신의 삶을 보내고 싶지 않아 : 좋은 시리얼을 - 의심 할 여지없이 느린 완벽하게 구현 버전 관용 수동 구현에 비해 동안 - 일반적으로 대부분의 사람들에게 좋은 타협
마크 Gravell

1
@BjarkeCK 나는 강력히 동의하지 않습니다. 대부분의 사람들에게는 원격으로 유용 하지도 않습니다 . 다음은 무엇입니까-매일 우리 자신의 컬렉션을 작성합니까? 아니오 :이 일을 합리적으로 잘 수행하는 것은 어렵습니다 . 물론, 실제로 가장 빠른 출력이 필요하다면 손을 더럽혀 야 할 것입니다.하지만 대부분의 사람들에게 이렇게하는 것은 시간 낭비 가 될 것 입니다. 기껏 해야 훨씬 더 오래 걸릴 것입니다. 아마도 그들의 코드는 버그가 많고 신뢰할 수 없으며 사용 가능한 라이브러리를 사용하는 것보다 느릴 것입니다. 대부분의 사람들은 이 미뉴 태가 아닌 앱에 필요한 것에 집중해야합니다 .
Marc Gravell

33

5
그것은 속도가 아닙니다. 그것은 느림입니다. 링크 된 기사에서 "작을수록 좋습니다"라고 말합니다.
Timur Nuriyasov

2
시간의 @TimurNuriyasov이 작업을 수행했다
맥심

2
그래서 바이너리가 가장 느리다고 말합니까? 나는 그렇게 생각하지 않는다! 나는 그것이 시간이 아니라 속도를 올바르게 지칭한다고 생각합니다.
Javid

2
바이너리가 가장 느립니다. 스스로 해보십시오. 그러나 나는 그것이 다형성 객체 (인터페이스 등) 제대로 작동하려면 물건을 해결 사용자 정의를 필요로하지 않기 때문에 그것이 가장 쉬운 말할 것
Kamarey

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-100 개가 아닌 1-10,000 개로 늘 렸습니다. 결과는 훨씬 더 명확 해 보였습니다.

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는 적어도 10 배 이상 성능이 훨씬 뛰어납니다.

YMMV.


1
아마도 BinaryFormatter는 배열로 정말 빠릅니다.
Behrooz

4
가능합니다 ...하지만 언급 된 조건 하에서 결과는 극적이었습니다. 여기서 교훈은 한 가지 방법이 모든 상황에서 가장 성능이 좋다고 믿지 않는다는 것입니다. 테스트와 벤치마킹은 항상 깨달았습니다.
Jeremy Holovacs

C ++에서 객체 직렬화는 약 100 배 더 빠릅니다!
Mario M

매우 흥미로운! 모두가 protobuf가 가장 빠르다고 주장했지만 이것은 고통스럽게 느리다는 것을 분명히 보여줍니다. 여기 믹스에 내 BinaronSerializer을 추가 dotnetfiddle.net/gOqQ7p - 그것은 배열 이미 정말 빠른 경우 BinaryFormatter로 거의 두 배 빠른 속도입니다.
Zach Saw

16

Protobuf는 매우 빠릅니다.

이 시스템의 성능 및 구현에 대한 자세한 정보는 http://code.google.com/p/protobuf-net/wiki/Performance 를 참조 하십시오 .


Protobuf를 사용하는 데 단점이 있습니까?
Robert Jeppesen

11
개체에 주석을 달아야합니다. Protobuf는 serializer가하는 것처럼 필드 이름과 유형을 저장하지 않지만 실제 유형에서 가져옵니다. 이것이 대상 파일이 훨씬 작은 이유 중 하나입니다. 문서는이 모든 것을 설명합니다. 나는 그것을 한동안 사용해 왔으며 빠른 (비) 직렬화와 작은 대상 파일이 필요하다면 protobuf가 정말 갈 길입니다.
Pieter van Ginkel

답변에 추가하기 위해 C #에서 Protobut를 사용하는 전체 소스 코드 샘플이 있습니까?
Kiquenet 2013

그렇게 빠르지 않습니다 ... 사실, 매우 매우 빠른 직렬 변환기에 비해 상당히 느립니다. dotnetfiddle.net/gOqQ7p
Zach Saw

@ZachSaw는 정수 배열을 다루는 경우만큼 빠르지는 않지만 (예를 들어) 정수만 직렬화하는 사람은 거의 없습니다. 많은 구성원이 포함 된 중첩 된 복합 유형을 처리하기 시작할 때 속도 이점 (또는 적어도 저는 그렇습니다)을 볼 수 있습니다.
matt.rothmeyer

15

초고속이라고 주장하는 또 다른 직렬 변환기는 netserializer 입니다.

그들의 사이트에 제공된 데이터는 protobuf보다 2x-4x의 성능을 보여줍니다 . 나는 이것을 직접 시도하지 않았지만 다양한 옵션을 평가하고 있다면 이것을 시도하십시오.


3
방금 내 응용 프로그램에서 NetSerializer를 사용해 보았는데 놀라 울 정도로 작동합니다. 시도해 볼 가치가 있습니다.
Galen

netserializer는 라이브러리가 어떤 형식으로 시작해야하는지 알지 못하거나 사용자가 개체를 직렬화 가능으로 표시하도록하는 옵션이있는 "사용자"개체를 직렬화하는 데 적합하지 않습니다.
Zach Saw

6

.net에 포함 된 이진 직렬 변환기는 XmlSerializer보다 빠릅니다. 또는 protobuf, json, ...

그러나 일부의 경우 속성을 추가하거나 메타 데이터를 추가하는 다른 방법이 필요합니다. 예를 들어 ProtoBuf는 내부적으로 숫자 속성 ID를 사용하며 매핑은 다른 메커니즘에 의해 어떻게 든 보존되어야합니다. 버전 관리는 serializer에서 사소한 일이 아닙니다.


예, 실제로 매우 빠르며 Xml보다 훨씬 더 많은 케이스 / 유형을 처리합니다.
leppie

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
어떤 버그를 언급하고 있습니까?
Jeremy Holovacs

0

괜찮은 성능을 가진 Salar.Bois serializer를 사용해 볼 수 있습니다 . 페이로드 크기에 초점을 맞추지 만 좋은 성능도 제공합니다.

결과를 직접보고 비교하려는 경우 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.13ms

편집 : CGbR 0.4.3부터 이진 직렬 변환기는 DateTime을 지원합니다. 불행히도이 DateTime.ToBinary방법은 엄청나게 느립니다. 빨리 좀 더 빨리 교체하겠습니다.

Edit2 : UTC DateTime를 호출 하여 사용 ToUniversalTime()하면 성능이 복원되고 1.669ms에 클럭됩니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.