From 7c503b4a61ec2b8fddb77a36df2566a39ebb96a7 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Sun, 10 Mar 2019 22:11:55 +0900 Subject: [PATCH 1/5] Add SerializerBenchmark project --- MessagePack.sln | 20 +- .../SerializerBenchmark/BenchmarkConfig.cs | 68 ++ .../SerializerBenchmark/ExtensionMethods.cs | 142 +++ .../Fixture/BooleanValueFixture.cs | 15 + .../Fixture/ByteValueFixture.cs | 15 + .../Fixture/DateTimeOffsetValueFixture.cs | 16 + .../Fixture/DateTimeValueFixture.cs | 18 + .../Fixture/DecimalValueFixture.cs | 15 + .../Fixture/DoubleValueFixture.cs | 15 + .../Fixture/EnumValueFixture.cs | 23 + .../Fixture/ExpressionTreeFixture.cs | 243 +++++ .../Fixture/FloatValueFixture.cs | 15 + .../Fixture/GuidValueFixture.cs | 14 + .../Fixture/IValueFixture.cs | 10 + .../Fixture/IntValueFixture.cs | 15 + .../Fixture/LongValueFixture.cs | 15 + .../Fixture/OtherPrimitiveFixtures.cs | 65 ++ .../Fixture/ShortValueFixture.cs | 15 + .../Fixture/StringValueFixture.cs | 27 + .../SerializerBenchmark/IGenericEquality.cs | 8 + .../MessagePack_1_7_3_6.dll | Bin 0 -> 283136 bytes .../SerializerBenchmark/Models/AccessToken.cs | 43 + .../Models/AccountMerge.cs | 36 + .../SerializerBenchmark/Models/Answer.cs | 142 +++ benchmark/SerializerBenchmark/Models/Badge.cs | 73 ++ .../SerializerBenchmark/Models/Comment.cs | 88 ++ benchmark/SerializerBenchmark/Models/Error.cs | 35 + benchmark/SerializerBenchmark/Models/Event.cs | 55 + benchmark/SerializerBenchmark/Models/Feed.cs | 688 +++++++++++++ .../SerializerBenchmark/Models/FlagOption.cs | 66 ++ .../SerializerBenchmark/Models/InboxItem.cs | 83 ++ benchmark/SerializerBenchmark/Models/Info.cs | 272 +++++ .../SerializerBenchmark/Models/NetworkUser.cs | 76 ++ .../Models/Notification.cs | 68 ++ benchmark/SerializerBenchmark/Models/Post.cs | 112 ++ .../SerializerBenchmark/Models/Privilege.cs | 35 + .../SerializerBenchmark/Models/Question.cs | 359 +++++++ .../Models/QuestionTimeline.cs | 83 ++ .../SerializerBenchmark/Models/Reputation.cs | 72 ++ .../Models/ReputationHistory.cs | 83 ++ .../SerializerBenchmark/Models/Revision.cs | 108 ++ .../Models/SearchExcerpt.cs | 119 +++ .../SerializerBenchmark/Models/ShallowUser.cs | 68 ++ .../Models/SuggestedEdit.cs | 78 ++ benchmark/SerializerBenchmark/Models/Tag.cs | 62 ++ .../SerializerBenchmark/Models/TagScore.cs | 35 + .../SerializerBenchmark/Models/TagSynonym.cs | 46 + .../SerializerBenchmark/Models/TagWiki.cs | 58 ++ .../SerializerBenchmark/Models/TopTag.cs | 50 + benchmark/SerializerBenchmark/Models/User.cs | 190 ++++ .../Models/UserTimeline.cs | 88 ++ .../Models/WritePermission.cs | 55 + benchmark/SerializerBenchmark/Program.cs | 13 + .../SerializerBenchmark.cs | 953 ++++++++++++++++++ .../SerializerBenchmark.csproj | 45 + .../Serializers/BinaryFormatter.cs | 24 + .../Serializers/DataContractSerializer.cs | 24 + .../Serializers/FsPicklerSerializer.cs | 26 + .../Serializers/HyperionSerializer.cs | 26 + .../Serializers/JilSerializer.cs | 16 + .../Serializers/JsonNetSerializer.cs | 33 + .../Serializers/MessagePackSerializer.cs | 56 + .../Serializers/MsgPackCliSerializer.cs | 14 + .../Serializers/ProtobufSerializer.cs | 23 + .../Serializers/SerializerBase.cs | 13 + .../Serializers/SpanJsonSerializer.cs | 14 + .../Serializers/Utf8JsonSerializer.cs | 14 + src/MessagePack/MessagePack.csproj | 7 + 68 files changed, 5498 insertions(+), 3 deletions(-) create mode 100644 benchmark/SerializerBenchmark/BenchmarkConfig.cs create mode 100644 benchmark/SerializerBenchmark/ExtensionMethods.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/BooleanValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/ByteValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/DateTimeOffsetValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/DateTimeValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/DecimalValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/DoubleValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/EnumValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/ExpressionTreeFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/FloatValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/GuidValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/IValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/IntValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/LongValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/OtherPrimitiveFixtures.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/ShortValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/Fixture/StringValueFixture.cs create mode 100644 benchmark/SerializerBenchmark/IGenericEquality.cs create mode 100644 benchmark/SerializerBenchmark/MessagePack_1_7_3_6.dll create mode 100644 benchmark/SerializerBenchmark/Models/AccessToken.cs create mode 100644 benchmark/SerializerBenchmark/Models/AccountMerge.cs create mode 100644 benchmark/SerializerBenchmark/Models/Answer.cs create mode 100644 benchmark/SerializerBenchmark/Models/Badge.cs create mode 100644 benchmark/SerializerBenchmark/Models/Comment.cs create mode 100644 benchmark/SerializerBenchmark/Models/Error.cs create mode 100644 benchmark/SerializerBenchmark/Models/Event.cs create mode 100644 benchmark/SerializerBenchmark/Models/Feed.cs create mode 100644 benchmark/SerializerBenchmark/Models/FlagOption.cs create mode 100644 benchmark/SerializerBenchmark/Models/InboxItem.cs create mode 100644 benchmark/SerializerBenchmark/Models/Info.cs create mode 100644 benchmark/SerializerBenchmark/Models/NetworkUser.cs create mode 100644 benchmark/SerializerBenchmark/Models/Notification.cs create mode 100644 benchmark/SerializerBenchmark/Models/Post.cs create mode 100644 benchmark/SerializerBenchmark/Models/Privilege.cs create mode 100644 benchmark/SerializerBenchmark/Models/Question.cs create mode 100644 benchmark/SerializerBenchmark/Models/QuestionTimeline.cs create mode 100644 benchmark/SerializerBenchmark/Models/Reputation.cs create mode 100644 benchmark/SerializerBenchmark/Models/ReputationHistory.cs create mode 100644 benchmark/SerializerBenchmark/Models/Revision.cs create mode 100644 benchmark/SerializerBenchmark/Models/SearchExcerpt.cs create mode 100644 benchmark/SerializerBenchmark/Models/ShallowUser.cs create mode 100644 benchmark/SerializerBenchmark/Models/SuggestedEdit.cs create mode 100644 benchmark/SerializerBenchmark/Models/Tag.cs create mode 100644 benchmark/SerializerBenchmark/Models/TagScore.cs create mode 100644 benchmark/SerializerBenchmark/Models/TagSynonym.cs create mode 100644 benchmark/SerializerBenchmark/Models/TagWiki.cs create mode 100644 benchmark/SerializerBenchmark/Models/TopTag.cs create mode 100644 benchmark/SerializerBenchmark/Models/User.cs create mode 100644 benchmark/SerializerBenchmark/Models/UserTimeline.cs create mode 100644 benchmark/SerializerBenchmark/Models/WritePermission.cs create mode 100644 benchmark/SerializerBenchmark/Program.cs create mode 100644 benchmark/SerializerBenchmark/SerializerBenchmark.cs create mode 100644 benchmark/SerializerBenchmark/SerializerBenchmark.csproj create mode 100644 benchmark/SerializerBenchmark/Serializers/BinaryFormatter.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/DataContractSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/FsPicklerSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/HyperionSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/JilSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/JsonNetSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/MsgPackCliSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/SerializerBase.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/SpanJsonSerializer.cs create mode 100644 benchmark/SerializerBenchmark/Serializers/Utf8JsonSerializer.cs diff --git a/MessagePack.sln b/MessagePack.sln index 96b97561..e5e81d65 100644 --- a/MessagePack.sln +++ b/MessagePack.sln @@ -64,6 +64,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution .gitignore = .gitignore EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmark", "benchmark", "{51A614B0-E583-4DD2-AC7D-6A65634582E0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SerializerBenchmark", "benchmark\SerializerBenchmark\SerializerBenchmark.csproj", "{4142EA80-FEF4-44A5-8553-1AE84BEBAFED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -266,6 +270,18 @@ Global {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x64.Build.0 = Release|Any CPU {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x86.ActiveCfg = Release|Any CPU {79C2B2CB-872A-4BA9-82DC-60F6DD77F940}.Release|x86.Build.0 = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|x64.ActiveCfg = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|x64.Build.0 = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|x86.ActiveCfg = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Debug|x86.Build.0 = Debug|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|Any CPU.Build.0 = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|x64.ActiveCfg = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|x64.Build.0 = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|x86.ActiveCfg = Release|Any CPU + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -287,9 +303,7 @@ Global {2A32A538-BA26-4D89-85D0-E4249AFA0837} = {BF4C4202-5015-4FBD-80E6-D0F36A06F700} {10AD85DD-929D-49B8-BD43-45242C2644B7} = {86309CF6-0054-4CE3-BFD3-CA0AA7DB17BC} {79C2B2CB-872A-4BA9-82DC-60F6DD77F940} = {19FE674A-AC94-4E7E-B24C-2285D1D04CDE} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {26F0752B-06F7-44AD-BFEE-8F2E36B3AA27} + {4142EA80-FEF4-44A5-8553-1AE84BEBAFED} = {51A614B0-E583-4DD2-AC7D-6A65634582E0} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B3911209-2DBF-47F8-98F6-BBC0EDFE63DE} diff --git a/benchmark/SerializerBenchmark/BenchmarkConfig.cs b/benchmark/SerializerBenchmark/BenchmarkConfig.cs new file mode 100644 index 00000000..4e72a985 --- /dev/null +++ b/benchmark/SerializerBenchmark/BenchmarkConfig.cs @@ -0,0 +1,68 @@ +using Benchmark.Serializers; +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Diagnosers; +using BenchmarkDotNet.Environments; +using BenchmarkDotNet.Exporters; +using BenchmarkDotNet.Exporters.Csv; +using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Order; +using BenchmarkDotNet.Reports; +using BenchmarkDotNet.Running; +using System.Collections.Generic; +using System.Linq; + +namespace Benchmark +{ + public class BenchmarkConfig : ManualConfig + { + public BenchmarkConfig() + { + // run quickly:) + var baseConfig = Job.ShortRun.WithIterationCount(1).WithWarmupCount(1); + + // Add(baseConfig.With(Runtime.Clr).With(Jit.RyuJit).With(Platform.X64)); + Add(baseConfig.With(Runtime.Core).With(Jit.RyuJit).With(Platform.X64)); + + Add(MarkdownExporter.GitHub); + Add(CsvExporter.Default); + Add(MemoryDiagnoser.Default); + + this.Set(new CustomOrderer()); + } + + // 0.11.4 has bug of set CustomOrderer https://github.com/dotnet/BenchmarkDotNet/issues/1070 + // so skip update to 0.11.4. + + public class CustomOrderer : IOrderer + { + public bool SeparateLogicalGroups => false; + + public IEnumerable GetExecutionOrder(BenchmarkCase[] benchmarksCase) + { + return benchmarksCase; + } + + public string GetHighlightGroupKey(BenchmarkCase benchmarkCase) + { + return benchmarkCase.Descriptor.MethodIndex.ToString(); + } + + public string GetLogicalGroupKey(IConfig config, BenchmarkCase[] allBenchmarksCases, BenchmarkCase benchmarkCase) + { + return null; + } + + public IEnumerable> GetLogicalGroupOrder(IEnumerable> logicalGroups) + { + return logicalGroups; + } + + public IEnumerable GetSummaryOrder(BenchmarkCase[] benchmarksCases, Summary summary) + { + return benchmarksCases + .OrderBy(x => x.Descriptor.WorkloadMethod.Name) + .ThenBy(x => x.Parameters.Items.Select(y => y.Value).OfType().First().GetType().Name); + } + } + } +} diff --git a/benchmark/SerializerBenchmark/ExtensionMethods.cs b/benchmark/SerializerBenchmark/ExtensionMethods.cs new file mode 100644 index 00000000..941c48db --- /dev/null +++ b/benchmark/SerializerBenchmark/ExtensionMethods.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Benchmark +{ + public class GenericEqualityComparer : IEqualityComparer where T : class, IGenericEquality + { + public static readonly GenericEqualityComparer Default = new GenericEqualityComparer(); + + public bool Equals(T x, T y) + { + return x.TrueEquals(y); + } + + public int GetHashCode(T obj) + { + return 0; // not fast, but not really important here + } + } + + public static class ExtensionMethods + { + public static bool TrueEqualsString(this IEnumerable a, IEnumerable b) + { + return a.SequenceEqual(b); + } + + public static bool TrueEqualsString(this string a, string b) + { + return a == b; + } + + public static bool TrueEquals(this T? a, T? b) + where T : struct + { + if (!a.HasValue && !b.HasValue) + { + return true; + } + if (!a.HasValue) + { + return false; + } + if (!b.HasValue) + { + return false; + } + + return a.Value.Equals(b.Value); + } + + public static bool TrueEquals(this T a, T b) + where T : class, IGenericEquality + { + if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) + { + return true; + } + + if (ReferenceEquals(a, null)) + { + return false; + } + + if (ReferenceEquals(b, null)) + { + return false; + } + + return a.Equals(b); + } + + public static bool TrueEqualsList(this IEnumerable a, IEnumerable b) + where T : class, IGenericEquality + { + return a.SequenceEqual(b, GenericEqualityComparer.Default); + } + + public static bool TrueEqualsListDynamic(this IEnumerable a, IEnumerable b) + where T : class, IGenericEquality + { + if (ReferenceEquals(a, null) && ReferenceEquals(b, null)) + { + return true; + } + + if (ReferenceEquals(a, null)) + { + return false; + } + if (ReferenceEquals(b, null)) + { + return false; + } + + using (var e1 = a.GetEnumerator()) + using (var e2 = b.GetEnumerator()) + { + while (true) + { + var e1Next = e1.MoveNext(); + var e2Next = e2.MoveNext(); + if (e1Next != e2Next) + { + return false; + } + if (!e1Next && !e2Next) + { + break; + } + var c1 = e1.Current; + var c2 = e2.Current; + + if (c1 == null && c2 != null) + { + return false; + } + if (c2 == null && c1 != null) + { + return false; + } + if (!c1.EqualsDynamic(c2)) + { + return false; + } + } + } + + return true; + } + + public static bool IsTypedList(this Type type) + { + return + type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>) || + type.GetTypeInfo().GetInterfaces().Any(i => + i.GetTypeInfo().IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>)); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/BooleanValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/BooleanValueFixture.cs new file mode 100644 index 00000000..bb600ce5 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/BooleanValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class BooleanValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(bool); + + public object Generate() + { + return _prng.Next() % 2 == 1; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/ByteValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/ByteValueFixture.cs new file mode 100644 index 00000000..d0833179 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/ByteValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class ByteValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(byte); + + public object Generate() + { + return (byte) (_prng.Next() & 0xFF); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/DateTimeOffsetValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/DateTimeOffsetValueFixture.cs new file mode 100644 index 00000000..f7302c7a --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/DateTimeOffsetValueFixture.cs @@ -0,0 +1,16 @@ +using System; + +namespace Benchmark.Fixture +{ + public class DateTimeOffsetValueFixture : IValueFixture + { + private long _lastValue; + public Type Type { get; } = typeof(DateTimeOffset); + + public object Generate() + { + _lastValue += 1000; + return DateTimeOffset.FromUnixTimeMilliseconds(_lastValue); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/DateTimeValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/DateTimeValueFixture.cs new file mode 100644 index 00000000..b64d5794 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/DateTimeValueFixture.cs @@ -0,0 +1,18 @@ +using System; + +namespace Benchmark.Fixture +{ + public class DateTimeValueFixture : IValueFixture + { + private long _lastValue; + private static readonly long Offset = new DateTime(1970, 1,1,0,0,0).ToFileTime(); + public Type Type { get; } = typeof(DateTime); + + public object Generate() + { + _lastValue += 1000; + var dt = DateTime.FromFileTime(_lastValue+Offset); + return dt; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/DecimalValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/DecimalValueFixture.cs new file mode 100644 index 00000000..5ab727ae --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/DecimalValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class DecimalValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(decimal); + + public object Generate() + { + return _prng.Next() + 0.66m; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/DoubleValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/DoubleValueFixture.cs new file mode 100644 index 00000000..7eb0b1ad --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/DoubleValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class DoubleValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(double); + + public object Generate() + { + return _prng.Next() + 0.5d; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/EnumValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/EnumValueFixture.cs new file mode 100644 index 00000000..cf944d42 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/EnumValueFixture.cs @@ -0,0 +1,23 @@ +using System; + +namespace Benchmark.Fixture +{ + public class EnumValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + private readonly string[] _values; + + public EnumValueFixture(Type type) + { + Type = type; + _values = Enum.GetNames(Type); + } + + public Type Type { get; } + + public object Generate() + { + return Enum.Parse(Type, _values[_prng.Next(_values.Length)]); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/ExpressionTreeFixture.cs b/benchmark/SerializerBenchmark/Fixture/ExpressionTreeFixture.cs new file mode 100644 index 00000000..bede1abc --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/ExpressionTreeFixture.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +namespace Benchmark.Fixture +{ + public class ExpressionTreeFixture + { + private readonly ConcurrentDictionary> _functorCache = + new ConcurrentDictionary>(); + + private readonly Dictionary _valueFixtures = new Dictionary(); + + public ExpressionTreeFixture() + { + IValueFixture[] fixtures = new IValueFixture[] + { + new StringValueFixture(), + new IntValueFixture(), + new GuidValueFixture(), + new DateTimeOffsetValueFixture(), + new DateTimeValueFixture(), + new BooleanValueFixture(), + new DecimalValueFixture(), + new LongValueFixture(), + new FloatValueFixture(), + new DoubleValueFixture(), + new ByteValueFixture(), + new ShortValueFixture(), + new ByteArrayFixture(), + new SByteValueFixture(), + new UShortValueFixture(), + new UInt32ValueFixture(), + new UInt64ValueFixture(), + new CharValueFixture() + }; + + foreach (var item in fixtures) + { + _valueFixtures.Add(item.Type, item); + } + } + + public object Create(Type type, int repeatCount = 1, int recursiveCount = 1) + { + var functor = _functorCache.GetOrAdd(type, AddFunctor); + return functor(repeatCount, recursiveCount); + } + + private Func AddFunctor(Type type) + { + var repeatCount = Expression.Parameter(typeof(int), "repeatCount"); + var recursiveCount = Expression.Parameter(typeof(int), "recursiveCount"); + var subExpressions = new List(); + var typedOutput = Expression.Variable(type, "typedOutput"); + if (_valueFixtures.ContainsKey(type) || type.IsArray || type.IsTypedList() + ) // they can be generated directly + { + var expression = GenerateValue(typedOutput, repeatCount, recursiveCount, type); + subExpressions.Add(expression); + } + else + { + subExpressions.Add(Expression.Assign(typedOutput, Expression.New(type))); + var typeProps = type.GetProperties(); + foreach (var propertyInfo in typeProps) + { + if (!propertyInfo.CanWrite) + { + continue; + } + var propertyType = propertyInfo.PropertyType; + var isRecursion = IsRecursion(type, propertyType) || IsRecursion(propertyType, type); + var memberAccess = Expression.MakeMemberAccess(typedOutput, propertyInfo); + var expression = GenerateValue(memberAccess, repeatCount, + isRecursion ? Expression.Decrement(recursiveCount) : (Expression)recursiveCount, propertyType); + subExpressions.Add(expression); + } + } + var returnTarget = Expression.Label(typeof(object)); + var returnLabel = Expression.Label(returnTarget, Expression.Convert(typedOutput, typeof(object))); + subExpressions.Add(returnLabel); + var block = Expression.Block(new[] { typedOutput }, subExpressions); + var lambda = Expression.Lambda>(block, repeatCount, recursiveCount); + return lambda.Compile(); + } + + private bool IsRecursion(Type parentType, Type type) + { + if (type == parentType) + { + return true; + } + if (parentType.IsTypedList()) + { + var childType = parentType.GetGenericArguments()[0]; + return IsRecursion(type, childType); + } + if (parentType.IsArray) + { + var elementType = parentType.GetElementType(); + return IsRecursion(type, elementType); + } + if (Nullable.GetUnderlyingType(parentType) != null) + { + var nullableType = Nullable.GetUnderlyingType(parentType); + return IsRecursion(type, nullableType); + } + return false; + } + + private Expression GenerateValue(Expression generatedValue, Expression repeatCount, Expression recursiveCount, + Type type) + { + var result = new List(); + if (_valueFixtures.TryGetValue(type, out var valueFixture)) + { + var generateMethodInfo = valueFixture.GetType().GetMethod(nameof(IValueFixture.Generate)); + result.Add(Expression.Assign(generatedValue, + Expression.Convert(Expression.Call(Expression.Constant(valueFixture), generateMethodInfo), + generatedValue.Type))); + } + else if (type.IsTypedList()) + { + var expressionList = new List(); + var elementType = type.GetGenericArguments()[0]; + expressionList.Add(Expression.Assign(generatedValue, Expression.New(type))); + var index = Expression.Parameter(typeof(int), "i"); + var addMi = type.GetMethod("Add", new[] { elementType }); + var childValue = Expression.Parameter(elementType); + var loopBlock = new List + { + GenerateValue(childValue, repeatCount, recursiveCount, elementType), + Expression.Call(generatedValue, addMi, childValue) + }; + if (loopBlock.Count > 0) + { + var loopContent = Expression.Block(new[] { childValue, index }, loopBlock); + expressionList.Add(ForLoop(index, repeatCount, loopContent)); + } + result.Add(MakeIfExpression(recursiveCount, expressionList)); + } + else if (type.IsArray) + { + var elementType = type.GetElementType(); + var index = Expression.Parameter(typeof(int), "i"); + var arrayList = new List + { + Expression.Assign(generatedValue, Expression.NewArrayBounds(elementType, repeatCount)), + ForLoop(index, repeatCount, + GenerateValue(Expression.ArrayAccess(generatedValue, index), repeatCount, recursiveCount, + elementType)) + }; + result.Add(MakeIfExpression(recursiveCount, arrayList)); + } + else if (Nullable.GetUnderlyingType(type) != null) + { + var elementType = Nullable.GetUnderlyingType(type); + result.Add(GenerateValue(generatedValue, repeatCount, recursiveCount, elementType)); + } + else if (type.GetTypeInfo().IsEnum) + { + if (!_valueFixtures.TryGetValue(type, out valueFixture)) + { + valueFixture = new EnumValueFixture(type); + _valueFixtures.Add(valueFixture.Type, valueFixture); + } + result.Add(GenerateValue(generatedValue, repeatCount, recursiveCount, + type)); // call again for main method + } + else + { + result.Add(MakeIfExpression(recursiveCount, + InvokeCreate(type, generatedValue, repeatCount, recursiveCount))); + } + return result.Count > 1 ? Expression.Block(result) : result.Single(); + } + + private Expression InvokeCreate(Type type, Expression generatedValue, Expression repeatCount, + Expression recursiveCount) + { + var mi = typeof(ExpressionTreeFixture).GetMethod(nameof(Create), + new[] { typeof(Type), typeof(int), typeof(int) }); + return Expression.Assign(generatedValue, + Expression.Convert( + Expression.Call(Expression.Constant(this), mi, + new[] { Expression.Constant(type), repeatCount, recursiveCount }), + generatedValue.Type)); + } + + private Expression MakeIfExpression(Expression recursiveCount, params Expression[] input) + { + return Expression.IfThen(Expression.GreaterThanOrEqual(recursiveCount, Expression.Constant(0)), + input.Length > 1 ? Expression.Block(input) : input.Single()); + } + + private Expression MakeIfExpression(Expression recursiveCount, IList input) + { + return Expression.IfThen(Expression.GreaterThanOrEqual(recursiveCount, Expression.Constant(0)), + input.Count > 1 ? Expression.Block(input) : input.Single()); + } + + public T Create(int repeatCount = 1, int recursiveCount = 1) + { + return (T)Create(typeof(T), repeatCount, recursiveCount); + } + + public IEnumerable CreateMany(int count, int repeatCount = 1, int recursiveCount = 1) + { + return CreateMany(typeof(T), count, repeatCount, recursiveCount).Cast(); + } + + public IEnumerable CreateMany(Type type, int count, int repeatCount = 1, int recursiveCount = 1) + { + var functor = _functorCache.GetOrAdd(type, AddFunctor); + for (var i = 0; i < count; i++) + { + yield return functor(repeatCount, recursiveCount); + } + } + + public static Expression ForLoop(ParameterExpression index, Expression lengthExpression, Expression loopContent) + { + var breakLabel = Expression.Label("LoopBreak"); + var length = Expression.Variable(typeof(int), "length"); + var block = Expression.Block(new[] { index, length }, + Expression.Assign(index, Expression.Constant(0)), + Expression.Assign(length, lengthExpression), + Expression.Loop( + Expression.IfThenElse( + Expression.LessThan(index, length), + Expression.Block(loopContent, Expression.PostIncrementAssign(index)), + Expression.Break(breakLabel) + ), + breakLabel) + ); + return block; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/FloatValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/FloatValueFixture.cs new file mode 100644 index 00000000..c4ff9df7 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/FloatValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class FloatValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(float); + + public object Generate() + { + return (float) _prng.Next() % 10000 + 0.5f; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/GuidValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/GuidValueFixture.cs new file mode 100644 index 00000000..948e495f --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/GuidValueFixture.cs @@ -0,0 +1,14 @@ +using System; + +namespace Benchmark.Fixture +{ + public class GuidValueFixture : IValueFixture + { + public Type Type { get; } = typeof(Guid); + + public object Generate() + { + return Guid.NewGuid(); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/IValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/IValueFixture.cs new file mode 100644 index 00000000..b5128ccc --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/IValueFixture.cs @@ -0,0 +1,10 @@ +using System; + +namespace Benchmark.Fixture +{ + public interface IValueFixture + { + Type Type { get; } + object Generate(); + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/IntValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/IntValueFixture.cs new file mode 100644 index 00000000..54a57f3d --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/IntValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class IntValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(int); + + public object Generate() + { + return _prng.Next(); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/LongValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/LongValueFixture.cs new file mode 100644 index 00000000..a0f0ebf4 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/LongValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class LongValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(long); + + public object Generate() + { + return ((long) _prng.Next() << 32) | (uint) _prng.Next(); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/OtherPrimitiveFixtures.cs b/benchmark/SerializerBenchmark/Fixture/OtherPrimitiveFixtures.cs new file mode 100644 index 00000000..586b4614 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/OtherPrimitiveFixtures.cs @@ -0,0 +1,65 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Benchmark.Fixture +{ + public delegate T Converter(ReadOnlySpan buffer); + + public abstract class PrimitiveFixtureBase : IValueFixture + where T : unmanaged + { + private readonly Random rand = new Random(); + + public Type Type => typeof(T); + + public abstract object Generate(); + + protected unsafe object GenerateBytes(Converter converter) + { + Span buffer = stackalloc byte[sizeof(T)]; + rand.NextBytes(buffer); + return converter(buffer); + } + } + + public class SByteValueFixture : PrimitiveFixtureBase + { + public override object Generate() + { + return GenerateBytes(x => unchecked((sbyte)x[0])); + } + } + + public class UShortValueFixture : PrimitiveFixtureBase + { + public override object Generate() => GenerateBytes(BitConverter.ToUInt16); + } + + public class UInt32ValueFixture : PrimitiveFixtureBase + { + public override object Generate() => GenerateBytes(BitConverter.ToUInt32); + } + + public class UInt64ValueFixture : PrimitiveFixtureBase + { + public override object Generate() => GenerateBytes(BitConverter.ToUInt64); + } + + public class CharValueFixture : PrimitiveFixtureBase + { + public override object Generate() => GenerateBytes(BitConverter.ToChar); + } + + public class ByteArrayFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(byte[]); + + public object Generate() + { + var bytes = new byte[100]; + _prng.NextBytes(bytes); + return bytes; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/ShortValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/ShortValueFixture.cs new file mode 100644 index 00000000..fc75d0b5 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/ShortValueFixture.cs @@ -0,0 +1,15 @@ +using System; + +namespace Benchmark.Fixture +{ + public class ShortValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + public Type Type { get; } = typeof(short); + + public object Generate() + { + return (short) (_prng.Next() & 0xFFFF); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Fixture/StringValueFixture.cs b/benchmark/SerializerBenchmark/Fixture/StringValueFixture.cs new file mode 100644 index 00000000..17a74014 --- /dev/null +++ b/benchmark/SerializerBenchmark/Fixture/StringValueFixture.cs @@ -0,0 +1,27 @@ +using System; + +namespace Benchmark.Fixture +{ + public class StringValueFixture : IValueFixture + { + private readonly Random _prng = new Random(); + + public Type Type { get; } = typeof(string); + + public object Generate() + { + return Generate(8); + } + + private string Generate(int length) + { + const string chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + var cArray = new char[length]; + for (var i = 0; i < length; i++) + { + cArray[i] = chars[_prng.Next(chars.Length)]; + } + return new string(cArray); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/IGenericEquality.cs b/benchmark/SerializerBenchmark/IGenericEquality.cs new file mode 100644 index 00000000..ae24e6e0 --- /dev/null +++ b/benchmark/SerializerBenchmark/IGenericEquality.cs @@ -0,0 +1,8 @@ +namespace Benchmark +{ + public interface IGenericEquality + { + bool Equals(T obj); + bool EqualsDynamic(dynamic obj); + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/MessagePack_1_7_3_6.dll b/benchmark/SerializerBenchmark/MessagePack_1_7_3_6.dll new file mode 100644 index 0000000000000000000000000000000000000000..232ca15a5d3b1b7dc315d6b690d144e8612fc75a GIT binary patch literal 283136 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 + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string access_token { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public DateTime? expires_on_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public List scope { get; set; } + + public bool Equals(AccessToken obj) + { + return + access_token.TrueEqualsString(obj.access_token) || + expires_on_date.TrueEquals(obj.expires_on_date) || + account_id.TrueEquals(obj.account_id) || + scope.TrueEqualsString(obj.scope); + } + + public bool EqualsDynamic(dynamic obj) + { + return + access_token.TrueEqualsString((string)obj.access_token) || + expires_on_date.TrueEquals((DateTime?)obj.expires_on_date) || + account_id.TrueEquals((int?)obj.account_id) || + scope.TrueEqualsString((IEnumerable)obj.scope); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/AccountMerge.cs b/benchmark/SerializerBenchmark/Models/AccountMerge.cs new file mode 100644 index 00000000..32a4fcab --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/AccountMerge.cs @@ -0,0 +1,36 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class AccountMerge : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? old_account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? new_account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? merge_date { get; set; } + + public bool Equals(AccountMerge obj) + { + return + old_account_id.TrueEquals(obj.old_account_id) && + new_account_id.TrueEquals(obj.new_account_id) && + merge_date.TrueEquals(obj.merge_date); + } + + public bool EqualsDynamic(dynamic obj) + { + return + old_account_id.TrueEquals((int?) obj.old_account_id) && + new_account_id.TrueEquals((int?) obj.new_account_id) && + merge_date.TrueEquals((DateTime?) obj.merge_date); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Answer.cs b/benchmark/SerializerBenchmark/Models/Answer.cs new file mode 100644 index 00000000..ec0464b6 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Answer.cs @@ -0,0 +1,142 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Answer : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? answer_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? locked_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? last_edit_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public DateTime? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public DateTime? community_owned_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public bool? is_accepted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public ShallowUser owner { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public int? up_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public int? down_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public List comments { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public bool? upvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(19), oldmsgpack::MessagePack.Key(19 - 1), newmsgpack::MessagePack.Key(19 - 1)] + public bool? downvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(20), oldmsgpack::MessagePack.Key(20 - 1), newmsgpack::MessagePack.Key(20 - 1)] + public bool? accepted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(21), oldmsgpack::MessagePack.Key(21 - 1), newmsgpack::MessagePack.Key(21 - 1)] + public ShallowUser last_editor { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(22), oldmsgpack::MessagePack.Key(22 - 1), newmsgpack::MessagePack.Key(22 - 1)] + public int? comment_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(23), oldmsgpack::MessagePack.Key(23 - 1), newmsgpack::MessagePack.Key(23 - 1)] + public string body_markdown { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(24), oldmsgpack::MessagePack.Key(24 - 1), newmsgpack::MessagePack.Key(24 - 1)] + public string share_link { get; set; } + + public bool Equals(Answer obj) + { + return + accepted.TrueEquals(obj.accepted) && + answer_id.TrueEquals(obj.answer_id) && + body.TrueEqualsString(obj.body) && + body_markdown.TrueEqualsString(obj.body_markdown) && + comment_count.TrueEquals(obj.comment_count) && + comments.TrueEqualsList(obj.comments) && + community_owned_date.TrueEquals(obj.community_owned_date) && + creation_date.TrueEquals(obj.creation_date) && + down_vote_count.TrueEquals(obj.down_vote_count) && + downvoted.TrueEquals(obj.downvoted) && + is_accepted.TrueEquals(obj.is_accepted) && + last_activity_date.TrueEquals(obj.last_activity_date) && + last_edit_date.TrueEquals(obj.last_edit_date) && + last_editor.TrueEquals(obj.last_editor) && + link.TrueEqualsString(obj.link) && + locked_date.TrueEquals(obj.locked_date) && + owner.TrueEquals(obj.owner) && + question_id.TrueEquals(obj.question_id) && + score.TrueEquals(obj.score) && + share_link.TrueEqualsString(obj.share_link) && + tags.TrueEqualsString(obj.tags) && + title.TrueEqualsString(obj.title) && + up_vote_count.TrueEquals(obj.up_vote_count) && + upvoted.TrueEquals(obj.upvoted); + } + + public bool EqualsDynamic(dynamic obj) + { + return + accepted.TrueEquals((bool?) obj.accepted) && + answer_id.TrueEquals((int?) obj.answer_id) && + body.TrueEqualsString((string) obj.body) && + body_markdown.TrueEqualsString((string) obj.body_markdown) && + comment_count.TrueEquals((int?) obj.comment_count) && + comments.TrueEqualsListDynamic((IEnumerable) obj.comments) && + community_owned_date.TrueEquals((DateTime?) obj.community_owned_date) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + down_vote_count.TrueEquals((int?) obj.down_vote_count) && + downvoted.TrueEquals((bool?) obj.downvoted) && + is_accepted.TrueEquals((bool?) obj.is_accepted) && + last_activity_date.TrueEquals((DateTime?) obj.last_activity_date) && + last_edit_date.TrueEquals((DateTime?) obj.last_edit_date) && + (last_editor == null && obj.last_editor == null || last_editor.EqualsDynamic(obj.last_editor)) && + link.TrueEqualsString((string) obj.link) && + locked_date.TrueEquals((DateTime?) obj.locked_date) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + question_id.TrueEquals((int?) obj.question_id) && + score.TrueEquals((int?) obj.score) && + share_link.TrueEqualsString((string) obj.share_link) && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title.TrueEqualsString((string) obj.title) && + up_vote_count.TrueEquals((int?) obj.up_vote_count) && + upvoted.TrueEquals((bool?) obj.upvoted); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Badge.cs b/benchmark/SerializerBenchmark/Models/Badge.cs new file mode 100644 index 00000000..8cfa5b67 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Badge.cs @@ -0,0 +1,73 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum BadgeRank : byte + { + bronze = 3, + silver = 2, + gold = 1 + } + + public enum BadgeType + { + named = 1, + tag_based = 2 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Badge : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? badge_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public BadgeRank? rank { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? award_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public BadgeType? badge_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public ShallowUser user { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public string link { get; set; } + + public bool Equals(Badge obj) + { + return + award_count.TrueEquals(obj.award_count) && + badge_id.TrueEquals(obj.badge_id) && + badge_type.TrueEquals(obj.badge_type) && + description.TrueEqualsString(obj.description) && + link.TrueEqualsString(obj.link) && + name.TrueEqualsString(obj.name) && + rank.TrueEquals(obj.rank) && + user.TrueEquals(obj.user); + } + + public bool EqualsDynamic(dynamic obj) + { + return + award_count.TrueEquals((int?) obj.award_count) && + badge_id.TrueEquals((int?) obj.badge_id) && + badge_type.TrueEquals((BadgeType?) obj.badge_type) && + description.TrueEqualsString((string) obj.description) && + link.TrueEqualsString((string) obj.link) && + name.TrueEqualsString((string) obj.name) && + rank.TrueEquals((BadgeRank?) obj.rank) && + (user == null && obj.user == null || user.EqualsDynamic(obj.user)); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Comment.cs b/benchmark/SerializerBenchmark/Models/Comment.cs new file mode 100644 index 00000000..8daf4aba --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Comment.cs @@ -0,0 +1,88 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum PostType : byte + { + question = 1, + answer = 2 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Comment : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? comment_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public bool? edited { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public ShallowUser owner { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public ShallowUser reply_to_user { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public string body_markdown { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public bool? upvoted { get; set; } + + public bool Equals(Comment obj) + { + return + body.TrueEqualsString(obj.body) && + body_markdown.TrueEqualsString(obj.body_markdown) && + comment_id.TrueEquals(obj.comment_id) && + creation_date.TrueEquals(obj.creation_date) && + edited.TrueEquals(obj.edited) && + link.TrueEqualsString(obj.link) && + owner.TrueEquals(obj.owner) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + reply_to_user.TrueEquals(obj.reply_to_user) && + score.TrueEquals(obj.score) && + upvoted.TrueEquals(obj.upvoted); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + body_markdown.TrueEqualsString((string) obj.body_markdown) && + comment_id.TrueEquals((int?) obj.comment_id) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + edited.TrueEquals((bool?) obj.edited) && + link.TrueEqualsString((string) obj.link) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + (reply_to_user == null && obj.reply_to_user == null || + reply_to_user.EqualsDynamic(obj.reply_to_user)) && + score.TrueEquals((int?) obj.score) && + upvoted.TrueEquals((bool?) obj.upvoted); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Error.cs b/benchmark/SerializerBenchmark/Models/Error.cs new file mode 100644 index 00000000..c0ace9c3 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Error.cs @@ -0,0 +1,35 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Error : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? error_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string error_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string description { get; set; } + + public bool Equals(Error obj) + { + return + error_id.TrueEquals(obj.error_id) && + error_name.TrueEqualsString(obj.error_name) && + description.TrueEqualsString(obj.description); + } + + public bool EqualsDynamic(dynamic obj) + { + return + error_id.TrueEquals((int?) obj.error_id) && + error_name.TrueEqualsString((string) obj.error_name) && + description.TrueEqualsString((string) obj.description); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Event.cs b/benchmark/SerializerBenchmark/Models/Event.cs new file mode 100644 index 00000000..488768dc --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Event.cs @@ -0,0 +1,55 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum EventType : byte + { + question_posted = 1, + answer_posted = 2, + comment_posted = 3, + post_edited = 4, + user_created = 5 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Event : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public EventType? event_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? event_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string excerpt { get; set; } + + public bool Equals(Event obj) + { + return + creation_date.TrueEquals(obj.creation_date) && + event_id.TrueEquals(obj.event_id) && + event_type.TrueEquals(obj.event_type) && + excerpt.TrueEqualsString(obj.excerpt) && + link.TrueEqualsString(obj.link); + } + + public bool EqualsDynamic(dynamic obj) + { + return + creation_date.TrueEquals((DateTime?) obj.creation_date) && + event_id.TrueEquals((int?) obj.event_id) && + event_type.TrueEquals((EventType?) obj.event_type) && + excerpt.TrueEqualsString((string) obj.excerpt) && + link.TrueEqualsString((string) obj.link); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Feed.cs b/benchmark/SerializerBenchmark/Models/Feed.cs new file mode 100644 index 00000000..7640ecdf --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Feed.cs @@ -0,0 +1,688 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class MobileFeed : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public List hot_questions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public List inbox_items { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public List likely_to_answer_questions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public List reputation_events { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public List cross_site_interesting_questions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public List badges { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public List earned_privileges { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public List upcoming_privileges { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public List community_bulletins { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public List association_bonuses { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public List careers_job_ads { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public List banner_ads { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public long? before { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public long? since { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public int? account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public MobileUpdateNotice update_notice { get; set; } + + public bool Equals(MobileFeed obj) + { + return + account_id == obj.account_id && + association_bonuses.TrueEqualsList(obj.association_bonuses) && + badges.TrueEqualsList(obj.badges) && + banner_ads.TrueEqualsList(obj.banner_ads) && + before == obj.before && + careers_job_ads.TrueEqualsList(obj.careers_job_ads) && + community_bulletins.TrueEqualsList(obj.community_bulletins) && + cross_site_interesting_questions.TrueEqualsList(obj.cross_site_interesting_questions) && + earned_privileges.TrueEqualsList(obj.earned_privileges) && + hot_questions.TrueEqualsList(obj.hot_questions) && + inbox_items.TrueEqualsList(obj.inbox_items) && + likely_to_answer_questions.TrueEqualsList(obj.likely_to_answer_questions) && + reputation_events.TrueEqualsList(obj.reputation_events) && + since == obj.since && + upcoming_privileges.TrueEqualsList(obj.upcoming_privileges) && + update_notice.TrueEquals(obj.update_notice); + } + + public bool EqualsDynamic(dynamic obj) + { + return + account_id == (int?) obj.account_id && + association_bonuses.TrueEqualsListDynamic((IEnumerable) obj.association_bonuses) && + badges.TrueEqualsListDynamic((IEnumerable) obj.badges) && + banner_ads.TrueEqualsListDynamic((IEnumerable) obj.banner_ads) && + before == (long?) obj.before && + careers_job_ads.TrueEqualsListDynamic((IEnumerable) obj.careers_job_ads) && + community_bulletins.TrueEqualsListDynamic((IEnumerable) obj.community_bulletins) && + cross_site_interesting_questions.TrueEqualsListDynamic( + (IEnumerable) obj.cross_site_interesting_questions) && + earned_privileges.TrueEqualsListDynamic((IEnumerable) obj.earned_privileges) && + hot_questions.TrueEqualsListDynamic((IEnumerable) obj.hot_questions) && + inbox_items.TrueEqualsListDynamic((IEnumerable) obj.inbox_items) && + likely_to_answer_questions.TrueEqualsListDynamic( + (IEnumerable) obj.likely_to_answer_questions) && + reputation_events.TrueEqualsListDynamic((IEnumerable) obj.reputation_events) && + since == (long?) obj.since && + upcoming_privileges.TrueEqualsListDynamic((IEnumerable) obj.upcoming_privileges) && + (update_notice == null && obj.update_notice == null || update_notice.EqualsDynamic(obj.update_notice)); + } + } + + public interface IMobileFeedBase : IGenericEquality + { + int? group_id { get; set; } + long? added_date { get; set; } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileQuestion : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public long? question_creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public long? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public bool? is_deleted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public bool? has_accepted_answer { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileQuestion obj) + { + return + added_date == obj.added_date && + answer_count == obj.answer_count && + group_id == obj.group_id && + has_accepted_answer == obj.has_accepted_answer && + is_deleted == obj.is_deleted && + last_activity_date == obj.last_activity_date && + question_creation_date == obj.question_creation_date && + question_id == obj.question_id && + site == obj.site && + tags.TrueEqualsString(obj.tags) && + title == obj.title; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + answer_count == (int?) obj.answer_count && + group_id == (int?) obj.group_id && + has_accepted_answer == (bool?) obj.has_accepted_answer && + is_deleted == (bool?) obj.is_deleted && + last_activity_date == (long?) obj.last_activity_date && + question_creation_date == (long?) obj.question_creation_date && + question_id == (int?) obj.question_id && + site == (string) obj.site && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title == (string) obj.title; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileRepChange : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? rep_change { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileRepChange obj) + { + return + added_date == obj.added_date && + group_id == obj.group_id && + link == obj.link && + rep_change == obj.rep_change && + site == obj.site && + title == obj.title; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + group_id == (int?) obj.group_id && + link == (string) obj.link && + rep_change == (int?) obj.rep_change && + site == (string) obj.site && + title == (string) obj.title; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileInboxItem : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? answer_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? comment_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public long? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public string item_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileInboxItem obj) + { + return + added_date == obj.added_date && + answer_id == obj.answer_id && + body == obj.body && + comment_id == obj.comment_id && + creation_date == obj.creation_date && + group_id == obj.group_id && + item_type == obj.item_type && + link == obj.link && + question_id == obj.question_id && + site == obj.site && + title == obj.title; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + answer_id == (int?) obj.answer_id && + body == (string) obj.body && + comment_id == (int?) obj.comment_id && + creation_date == (long?) obj.creation_date && + group_id == (int?) obj.group_id && + item_type == (string) obj.item_type && + link == (string) obj.link && + question_id == (int?) obj.question_id && + site == (string) obj.site && + title == (string) obj.title; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileBadgeAward : IMobileFeedBase + { + public enum BadgeRank : byte + { + bronze = 1, + silver = 2, + gold = 3 + } + + public enum BadgeType + { + named = 1, + tag_based = 2 + } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string badge_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string badge_description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? badge_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public BadgeRank? rank { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public BadgeType? badge_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileBadgeAward obj) + { + return + added_date == obj.added_date && + badge_description == obj.badge_description && + badge_id == obj.badge_id && + badge_name == obj.badge_name && + badge_type == obj.badge_type && + group_id == obj.group_id && + link == obj.link && + post_id == obj.post_id && + rank == obj.rank && + site == obj.site; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + badge_description == (string) obj.badge_description && + badge_id == (int?) obj.badge_id && + badge_name == (string) obj.badge_name && + badge_type == (BadgeType?) obj.badge_type && + group_id == (int?) obj.group_id && + link == (string) obj.link && + post_id == (int?) obj.post_id && + rank == (BadgeRank?) obj.rank && + site == (string) obj.site; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobilePrivilege : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string privilege_short_description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string privilege_long_description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? privilege_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? reputation_required { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobilePrivilege obj) + { + return + added_date == obj.added_date && + group_id == obj.group_id && + link == obj.link && + privilege_id == obj.privilege_id && + privilege_long_description == obj.privilege_long_description && + privilege_short_description == obj.privilege_short_description && + reputation_required == obj.reputation_required && + site == obj.site; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + group_id == (int?) obj.group_id && + link == (string) obj.link && + privilege_id == (int?) obj.privilege_id && + privilege_long_description == (string) obj.privilege_long_description && + privilege_short_description == (string) obj.privilege_short_description && + reputation_required == (int?) obj.reputation_required && + site == (string) obj.site; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileCommunityBulletin : IMobileFeedBase + { + public enum CommunityBulletinType : byte + { + blog_post = 1, + featured_meta_question = 2, + upcoming_event = 3 + } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public CommunityBulletinType? bulletin_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public long? begin_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public long? end_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public string custom_date_string { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public bool? is_deleted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public bool? has_accepted_answer { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public bool? is_promoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileCommunityBulletin obj) + { + return + added_date == obj.added_date && + answer_count == obj.answer_count && + begin_date == obj.begin_date && + bulletin_type == obj.bulletin_type && + custom_date_string == obj.custom_date_string && + end_date == obj.end_date && + group_id == obj.group_id && + has_accepted_answer == obj.has_accepted_answer && + is_deleted == obj.is_deleted && + is_promoted == obj.is_promoted && + link == obj.link && + site == obj.site && + tags.TrueEqualsString(obj.tags) && + title == obj.title; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + answer_count == (int?) obj.answer_count && + begin_date == (long?) obj.begin_date && + bulletin_type == (CommunityBulletinType?) obj.bulletin_type && + custom_date_string == (string) obj.custom_date_string && + end_date == (long?) obj.end_date && + group_id == (int?) obj.group_id && + has_accepted_answer == (bool?) obj.has_accepted_answer && + is_deleted == (bool?) obj.is_deleted && + is_promoted == (bool?) obj.is_promoted && + link == (string) obj.link && + site == (string) obj.site && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title == (string) obj.title; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileAssociationBonus : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? amount { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileAssociationBonus obj) + { + return + added_date == obj.added_date && + amount == obj.amount && + group_id == obj.group_id && + site == obj.site; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + amount == (int?) obj.amount && + group_id == (int?) obj.group_id && + site == (string) obj.site; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileCareersJobAd : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? job_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string company_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string location { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileCareersJobAd obj) + { + return + added_date == obj.added_date && + company_name == obj.company_name && + group_id == obj.group_id && + job_id == obj.job_id && + link == obj.link && + location == obj.location && + title == obj.title; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + company_name == (string) obj.company_name && + group_id == (int?) obj.group_id && + job_id == (int?) obj.job_id && + link == (string) obj.link && + location == (string) obj.location && + title == (string) obj.title; + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileBannerAd : IMobileFeedBase + { + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public List images { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? group_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public long? added_date { get; set; } + + public bool Equals(MobileBannerAd obj) + { + return + added_date == obj.added_date && + group_id == obj.group_id && + images.TrueEqualsList(obj.images) && + link == obj.link; + } + + public bool EqualsDynamic(dynamic obj) + { + return + added_date == (long?) obj.added_date && + group_id == (int?) obj.group_id && + images.TrueEqualsListDynamic((IEnumerable) obj.images) && + link == (string) obj.link; + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileBannerAdImage : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string image_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? width { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? height { get; set; } + + public bool Equals(MobileBannerAdImage obj) + { + return + height == obj.height && + image_url == obj.image_url && + width == obj.width; + } + + public bool EqualsDynamic(dynamic obj) + { + return + height == (int?) obj.height && + image_url == (string) obj.image_url && + width == (int?) obj.width; + } + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public sealed class MobileUpdateNotice : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public bool? should_update { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string message { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string minimum_supported_version { get; set; } + + public bool Equals(MobileUpdateNotice obj) + { + return + message == obj.message && + minimum_supported_version == obj.minimum_supported_version && + should_update == obj.should_update; + } + + public bool EqualsDynamic(dynamic obj) + { + return + message == (string) obj.message && + minimum_supported_version == (string) obj.minimum_supported_version && + should_update == (bool?) obj.should_update; + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/FlagOption.cs b/benchmark/SerializerBenchmark/Models/FlagOption.cs new file mode 100644 index 00000000..49dc0dc1 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/FlagOption.cs @@ -0,0 +1,66 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class FlagOption : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? option_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public bool? requires_comment { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public bool? requires_site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public bool? requires_question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public List sub_options { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public bool? has_flagged { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? count { get; set; } + + public bool Equals(FlagOption obj) + { + return + count.TrueEquals(obj.count) && + description.TrueEqualsString(obj.description) && + has_flagged.TrueEquals(obj.has_flagged) && + option_id.TrueEquals(obj.option_id) && + requires_comment.TrueEquals(obj.requires_comment) && + requires_question_id.TrueEquals(obj.requires_question_id) && + requires_site.TrueEquals(obj.requires_site) && + sub_options.TrueEqualsList(obj.sub_options) && + title.TrueEqualsString(obj.title); + } + + public bool EqualsDynamic(dynamic obj) + { + return + count.TrueEquals((int?) obj.count) && + description.TrueEqualsString((string) obj.description) && + has_flagged.TrueEquals((bool?) obj.has_flagged) && + option_id.TrueEquals((int?) obj.option_id) && + requires_comment.TrueEquals((bool?) obj.requires_comment) && + requires_question_id.TrueEquals((bool?) obj.requires_question_id) && + requires_site.TrueEquals((bool?) obj.requires_site) && + sub_options.TrueEqualsListDynamic((IEnumerable) obj.sub_options) && + title.TrueEqualsString((string) obj.title); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/InboxItem.cs b/benchmark/SerializerBenchmark/Models/InboxItem.cs new file mode 100644 index 00000000..8996ceea --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/InboxItem.cs @@ -0,0 +1,83 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum InboxItemType + { + comment = 1, + chat_message = 2, + new_answer = 3, + careers_message = 4, + careers_invitations = 5, + meta_question = 6, + post_notice = 7, + moderator_message = 8 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class InboxItem : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public InboxItemType? item_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? answer_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? comment_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public bool? is_unread { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public Info.Site site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string link { get; set; } + + public bool Equals(InboxItem obj) + { + return + answer_id.TrueEquals(obj.answer_id) && + body.TrueEqualsString(obj.body) && + comment_id.TrueEquals(obj.comment_id) && + creation_date.TrueEquals(obj.creation_date) && + is_unread.TrueEquals(obj.is_unread) && + item_type.TrueEquals(obj.item_type) && + link.TrueEqualsString(obj.link) && + question_id.TrueEquals(obj.question_id) && + site.TrueEquals(obj.site) && + title.TrueEqualsString(obj.title); + } + + public bool EqualsDynamic(dynamic obj) + { + return + answer_id.TrueEquals((int?) obj.answer_id) && + body.TrueEqualsString((string) obj.body) && + comment_id.TrueEquals((int?) obj.comment_id) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + is_unread.TrueEquals((bool?) obj.is_unread) && + item_type.TrueEquals((InboxItemType?) obj.item_type) && + link.TrueEqualsString((string) obj.link) && + question_id.TrueEquals((int?) obj.question_id) && + (site == null && obj.site == null || site.EqualsDynamic(obj.site)) && + title.TrueEqualsString((string) obj.title); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Info.cs b/benchmark/SerializerBenchmark/Models/Info.cs new file mode 100644 index 00000000..7ef7e363 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Info.cs @@ -0,0 +1,272 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Info : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? total_questions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? total_unanswered { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? total_accepted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? total_answers { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public decimal? questions_per_minute { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public decimal? answers_per_minute { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? total_comments { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public int? total_votes { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? total_badges { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public decimal? badges_per_minute { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public int? total_users { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public int? new_active_users { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public string api_revision { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public Site site { get; set; } + + public bool Equals(Info obj) + { + return + answers_per_minute.TrueEquals(obj.answers_per_minute) && + api_revision.TrueEqualsString(obj.api_revision) && + badges_per_minute.TrueEquals(obj.badges_per_minute) && + new_active_users.TrueEquals(obj.new_active_users) && + questions_per_minute.TrueEquals(obj.questions_per_minute) && + site.TrueEquals(obj.site) && + total_accepted.TrueEquals(obj.total_accepted) && + total_answers.TrueEquals(obj.total_answers) && + total_badges.TrueEquals(obj.total_badges) && + total_comments.TrueEquals(obj.total_comments) && + total_questions.TrueEquals(obj.total_questions) && + total_unanswered.TrueEquals(obj.total_unanswered) && + total_users.TrueEquals(obj.total_users) && + total_votes.TrueEquals(obj.total_votes); + } + + public bool EqualsDynamic(dynamic obj) + { + return + answers_per_minute.TrueEquals((decimal?) obj.answers_per_minute) && + api_revision.TrueEqualsString((string) obj.api_revision) && + badges_per_minute.TrueEquals((decimal?) obj.badges_per_minute) && + new_active_users.TrueEquals((int?) obj.new_active_users) && + questions_per_minute.TrueEquals((decimal?) obj.questions_per_minute) && + (site == null && obj.site == null || site.EqualsDynamic(obj.site)) && + total_accepted.TrueEquals((int?) obj.total_accepted) && + total_answers.TrueEquals((int?) obj.total_answers) && + total_badges.TrueEquals((int?) obj.total_badges) && + total_comments.TrueEquals((int?) obj.total_comments) && + total_questions.TrueEquals((int?) obj.total_questions) && + total_unanswered.TrueEquals((int?) obj.total_unanswered) && + total_users.TrueEquals((int?) obj.total_users) && + total_votes.TrueEquals((int?) obj.total_votes); + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Site : IGenericEquality + { + public enum SiteState + { + normal, + closed_beta, + open_beta, + linked_meta + } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string site_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string logo_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string api_site_parameter { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string site_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string audience { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public string icon_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public List aliases { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public SiteState? site_state { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public Styling styling { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public DateTime? closed_beta_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public DateTime? open_beta_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public DateTime? launch_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public string favicon_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public List related_sites { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public string twitter_account { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public List markdown_extensions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public string high_resolution_icon_url { get; set; } + + public bool Equals(Site obj) + { + return + aliases.TrueEqualsString(obj.aliases) && + api_site_parameter.TrueEqualsString(obj.api_site_parameter) && + audience.TrueEqualsString(obj.audience) && + closed_beta_date.TrueEquals(obj.closed_beta_date) && + favicon_url.TrueEqualsString(obj.favicon_url) && + high_resolution_icon_url.TrueEqualsString(obj.high_resolution_icon_url) && + icon_url.TrueEqualsString(obj.icon_url) && + launch_date.TrueEquals(obj.launch_date) && + logo_url.TrueEqualsString(obj.logo_url) && + markdown_extensions.TrueEqualsString(obj.markdown_extensions) && + name.TrueEqualsString(obj.name) && + open_beta_date.TrueEquals(obj.open_beta_date) && + related_sites.TrueEqualsList(obj.related_sites) && + site_state.TrueEquals(obj.site_state) && + site_type.TrueEqualsString(obj.site_type) && + site_url.TrueEqualsString(obj.site_url) && + styling.TrueEquals(obj.styling) && + twitter_account.TrueEqualsString(obj.twitter_account); + } + + public bool EqualsDynamic(dynamic obj) + { + return + aliases.TrueEqualsString((IEnumerable) obj.aliases) && + api_site_parameter.TrueEqualsString((string) obj.api_site_parameter) && + audience.TrueEqualsString((string) obj.audience) && + closed_beta_date.TrueEquals((DateTime?) obj.closed_beta_date) && + favicon_url.TrueEqualsString((string) obj.favicon_url) && + high_resolution_icon_url.TrueEqualsString((string) obj.high_resolution_icon_url) && + icon_url.TrueEqualsString((string) obj.icon_url) && + launch_date.TrueEquals((DateTime?) obj.launch_date) && + logo_url.TrueEqualsString((string) obj.logo_url) && + markdown_extensions.TrueEqualsString((IEnumerable) obj.markdown_extensions) && + name.TrueEqualsString((string) obj.name) && + open_beta_date.TrueEquals((DateTime?) obj.open_beta_date) && + related_sites.TrueEqualsListDynamic((IEnumerable) obj.related_sites) && + site_state.TrueEquals((SiteState?) obj.site_state) && + site_type.TrueEqualsString((string) obj.site_type) && + site_url.TrueEqualsString((string) obj.site_url) && + (styling == null && obj.styling == null || styling.EqualsDynamic(obj.styling)) && + twitter_account.TrueEqualsString((string) obj.twitter_account); + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Styling : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string link_color { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string tag_foreground_color { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string tag_background_color { get; set; } + + public bool Equals(Styling obj) + { + return + link_color.TrueEqualsString(obj.link_color) && + tag_background_color.TrueEqualsString(obj.tag_background_color) && + tag_foreground_color.TrueEqualsString(obj.tag_foreground_color); + } + + public bool EqualsDynamic(dynamic obj) + { + return + link_color.TrueEqualsString((string) obj.link_color) && + tag_background_color.TrueEqualsString((string) obj.tag_background_color) && + tag_foreground_color.TrueEqualsString((string) obj.tag_foreground_color); + } + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class RelatedSite : IGenericEquality + { + public enum SiteRelation + { + parent, + meta, + chat + } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string site_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public SiteRelation? relation { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string api_site_parameter { get; set; } + + public bool Equals(RelatedSite obj) + { + return + name.TrueEqualsString(obj.name) && + relation.TrueEquals(obj.relation) && + api_site_parameter.TrueEqualsString(obj.api_site_parameter); + } + + public bool EqualsDynamic(dynamic obj) + { + return + name.TrueEqualsString((string) obj.name) && + relation.TrueEquals((SiteRelation?) obj.relation) && + api_site_parameter.TrueEqualsString((string) obj.api_site_parameter); + } + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/NetworkUser.cs b/benchmark/SerializerBenchmark/Models/NetworkUser.cs new file mode 100644 index 00000000..172d1f1f --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/NetworkUser.cs @@ -0,0 +1,76 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class NetworkUser : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string site_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string site_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? reputation { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public UserType? user_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public User.BadgeCount badge_counts { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public DateTime? last_access_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public int? question_count { get; set; } + + public bool Equals(NetworkUser obj) + { + return + account_id.TrueEquals(obj.account_id) && + answer_count.TrueEquals(obj.answer_count) && + badge_counts.TrueEquals(obj.badge_counts) && + creation_date.TrueEquals(obj.creation_date) && + last_access_date.TrueEquals(obj.last_access_date) && + question_count.TrueEquals(obj.question_count) && + reputation.TrueEquals(obj.reputation) && + site_name.TrueEqualsString(obj.site_name) && + site_url.TrueEqualsString(obj.site_url) && + user_id.TrueEquals(obj.user_id) && + user_type.TrueEquals(obj.user_type); + } + + public bool EqualsDynamic(dynamic obj) + { + return + account_id.TrueEquals((int?) obj.account_id) && + answer_count.TrueEquals((int?) obj.answer_count) && + (badge_counts == null && obj.badge_counts == null || badge_counts.EqualsDynamic(obj.badge_counts)) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + last_access_date.TrueEquals((DateTime?) obj.last_access_date) && + question_count.TrueEquals((int?) obj.question_count) && + reputation.TrueEquals((int?) obj.reputation) && + site_name.TrueEqualsString((string) obj.site_name) && + site_url.TrueEqualsString((string) obj.site_url) && + user_id.TrueEquals((int?) obj.user_id) && + user_type.TrueEquals((UserType?) obj.user_type); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Notification.cs b/benchmark/SerializerBenchmark/Models/Notification.cs new file mode 100644 index 00000000..b2d884c0 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Notification.cs @@ -0,0 +1,68 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum NotificationType : byte + { + generic = 1, + accounts_associated = 8, + badge_earned = 5, + profile_activity = 2, + bounty_expired = 3, + bounty_expires_in_one_day = 4, + bounty_expires_in_three_days = 6, + edit_suggested = 22, + new_privilege = 9, + post_migrated = 10, + moderator_message = 11, + registration_reminder = 12, + substantive_edit = 23, + reputation_bonus = 7, + bounty_grace_period_started = 24 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Notification : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public NotificationType? notification_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public Info.Site site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public bool? is_unread { get; set; } + + public bool Equals(Notification obj) + { + return + body.TrueEqualsString(obj.body) && + site.TrueEquals(obj.site) && + creation_date.TrueEquals(obj.creation_date) && + post_id.TrueEquals(obj.post_id) && + is_unread.TrueEquals(obj.is_unread); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + (site == null && obj.site == null || site.EqualsDynamic(obj.site)) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + post_id.TrueEquals((int?) obj.post_id) && + is_unread.TrueEquals((bool?) obj.is_unread); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Post.cs b/benchmark/SerializerBenchmark/Models/Post.cs new file mode 100644 index 00000000..fe0e85c8 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Post.cs @@ -0,0 +1,112 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Post : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public ShallowUser owner { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public DateTime? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public DateTime? last_edit_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? up_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public int? down_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public List comments { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public bool? upvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public bool? downvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public ShallowUser last_editor { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public int? comment_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public string body_markdown { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public string share_link { get; set; } + + public bool Equals(Post obj) + { + return + body.TrueEqualsString(obj.body) && + body_markdown.TrueEqualsString(obj.body_markdown) && + comment_count.TrueEquals(obj.comment_count) && + comments.TrueEqualsList(obj.comments) && + creation_date.TrueEquals(obj.creation_date) && + down_vote_count.TrueEquals(obj.down_vote_count) && + downvoted.TrueEquals(obj.downvoted) && + last_activity_date.TrueEquals(obj.last_activity_date) && + last_edit_date.TrueEquals(obj.last_edit_date) && + last_editor.TrueEquals(obj.last_editor) && + link.TrueEqualsString(obj.link) && + owner.TrueEquals(obj.owner) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + score.TrueEquals(obj.score) && + share_link.TrueEqualsString(obj.share_link) && + up_vote_count.TrueEquals(obj.up_vote_count) && + upvoted.TrueEquals(obj.upvoted); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + body_markdown.TrueEqualsString((string) obj.body_markdown) && + comment_count.TrueEquals((int?) obj.comment_count) && + comments.TrueEqualsListDynamic((IEnumerable) obj.comments) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + down_vote_count.TrueEquals((int?) obj.down_vote_count) && + downvoted.TrueEquals((bool?) obj.downvoted) && + last_activity_date.TrueEquals((DateTime?) obj.last_activity_date) && + last_edit_date.TrueEquals((DateTime?) obj.last_edit_date) && + (last_editor == null && obj.last_editor == null || last_editor.EqualsDynamic(obj.last_editor)) && + link.TrueEqualsString((string) obj.link) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + score.TrueEquals((int?) obj.score) && + share_link.TrueEqualsString((string) obj.share_link) && + up_vote_count.TrueEquals((int?) obj.up_vote_count) && + upvoted.TrueEquals((bool?) obj.upvoted); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Privilege.cs b/benchmark/SerializerBenchmark/Models/Privilege.cs new file mode 100644 index 00000000..ae07c15e --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Privilege.cs @@ -0,0 +1,35 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Privilege : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string short_description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? reputation { get; set; } + + public bool Equals(Privilege obj) + { + return + description.TrueEqualsString(obj.description) && + reputation.TrueEquals(obj.reputation) && + short_description.TrueEqualsString(obj.short_description); + } + + public bool EqualsDynamic(dynamic obj) + { + return + description.TrueEqualsString((string) obj.description) && + reputation.TrueEquals((int?) obj.reputation) && + short_description.TrueEqualsString((string) obj.short_description); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Question.cs b/benchmark/SerializerBenchmark/Models/Question.cs new file mode 100644 index 00000000..df6731a3 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Question.cs @@ -0,0 +1,359 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Question : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public DateTime? last_edit_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public DateTime? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? locked_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public DateTime? community_owned_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? accepted_answer_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public MigrationInfo migrated_to { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public MigrationInfo migrated_from { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public DateTime? bounty_closes_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public int? bounty_amount { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public DateTime? closed_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public DateTime? protected_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(19), oldmsgpack::MessagePack.Key(19 - 1), newmsgpack::MessagePack.Key(19 - 1)] + public string closed_reason { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(20), oldmsgpack::MessagePack.Key(20 - 1), newmsgpack::MessagePack.Key(20 - 1)] + public int? up_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(21), oldmsgpack::MessagePack.Key(21 - 1), newmsgpack::MessagePack.Key(21 - 1)] + public int? down_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(22), oldmsgpack::MessagePack.Key(22 - 1), newmsgpack::MessagePack.Key(22 - 1)] + public int? favorite_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(23), oldmsgpack::MessagePack.Key(23 - 1), newmsgpack::MessagePack.Key(23 - 1)] + public int? view_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(24), oldmsgpack::MessagePack.Key(24 - 1), newmsgpack::MessagePack.Key(24 - 1)] + public ShallowUser owner { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(25), oldmsgpack::MessagePack.Key(25 - 1), newmsgpack::MessagePack.Key(25 - 1)] + public List comments { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(26), oldmsgpack::MessagePack.Key(26 - 1), newmsgpack::MessagePack.Key(26 - 1)] + public List answers { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(27), oldmsgpack::MessagePack.Key(27 - 1), newmsgpack::MessagePack.Key(27 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(28), oldmsgpack::MessagePack.Key(28 - 1), newmsgpack::MessagePack.Key(28 - 1)] + public bool? is_answered { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(29), oldmsgpack::MessagePack.Key(29 - 1), newmsgpack::MessagePack.Key(29 - 1)] + public int? close_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(30), oldmsgpack::MessagePack.Key(30 - 1), newmsgpack::MessagePack.Key(30 - 1)] + public int? reopen_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(31), oldmsgpack::MessagePack.Key(31 - 1), newmsgpack::MessagePack.Key(31 - 1)] + public int? delete_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(32), oldmsgpack::MessagePack.Key(32 - 1), newmsgpack::MessagePack.Key(32 - 1)] + public Notice notice { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(33), oldmsgpack::MessagePack.Key(33 - 1), newmsgpack::MessagePack.Key(33 - 1)] + public bool? upvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(34), oldmsgpack::MessagePack.Key(34 - 1), newmsgpack::MessagePack.Key(34 - 1)] + public bool? downvoted { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(35), oldmsgpack::MessagePack.Key(35 - 1), newmsgpack::MessagePack.Key(35 - 1)] + public bool? favorited { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(36), oldmsgpack::MessagePack.Key(36 - 1), newmsgpack::MessagePack.Key(36 - 1)] + public ShallowUser last_editor { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(37), oldmsgpack::MessagePack.Key(37 - 1), newmsgpack::MessagePack.Key(37 - 1)] + public int? comment_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(38), oldmsgpack::MessagePack.Key(38 - 1), newmsgpack::MessagePack.Key(38 - 1)] + public string body_markdown { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(39), oldmsgpack::MessagePack.Key(39 - 1), newmsgpack::MessagePack.Key(39 - 1)] + public ClosedDetails closed_details { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(40), oldmsgpack::MessagePack.Key(40 - 1), newmsgpack::MessagePack.Key(40 - 1)] + public string share_link { get; set; } + + public bool Equals(Question obj) + { + return + accepted_answer_id.TrueEquals(obj.accepted_answer_id) && + answer_count.TrueEquals(obj.answer_count) && + answers.TrueEqualsList(obj.answers) && + body.TrueEqualsString(obj.body) && + body_markdown.TrueEqualsString(obj.body_markdown) && + bounty_amount.TrueEquals(obj.bounty_amount) && + bounty_closes_date.TrueEquals(obj.bounty_closes_date) && + close_vote_count.TrueEquals(obj.close_vote_count) && + closed_date.TrueEquals(obj.closed_date) && + closed_details.TrueEquals(obj.closed_details) && + closed_reason.TrueEqualsString(obj.closed_reason) && + comment_count.TrueEquals(obj.comment_count) && + comments.TrueEqualsList(obj.comments) && + community_owned_date.TrueEquals(obj.community_owned_date) && + creation_date.TrueEquals(obj.creation_date) && + delete_vote_count.TrueEquals(obj.delete_vote_count) && + down_vote_count.TrueEquals(obj.down_vote_count) && + downvoted.TrueEquals(obj.downvoted) && + favorite_count.TrueEquals(obj.favorite_count) && + favorited.TrueEquals(obj.favorited) && + is_answered.TrueEquals(obj.is_answered) && + last_activity_date.TrueEquals(obj.last_activity_date) && + last_edit_date.TrueEquals(obj.last_edit_date) && + last_editor.TrueEquals(obj.last_editor) && + link.TrueEqualsString(obj.link) && + locked_date.TrueEquals(obj.locked_date) && + migrated_from.TrueEquals(obj.migrated_from) && + migrated_to.TrueEquals(obj.migrated_to) && + notice.TrueEquals(obj.notice) && + owner.TrueEquals(obj.owner) && + protected_date.TrueEquals(obj.protected_date) && + question_id.TrueEquals(obj.question_id) && + reopen_vote_count.TrueEquals(obj.reopen_vote_count) && + score.TrueEquals(obj.score) && + share_link.TrueEqualsString(obj.share_link) && + tags.TrueEqualsString(obj.tags) && + title.TrueEqualsString(obj.title) && + up_vote_count.TrueEquals(obj.up_vote_count) && + upvoted.TrueEquals(obj.upvoted) && + view_count.TrueEquals(obj.view_count); + } + + public bool EqualsDynamic(dynamic obj) + { + return + accepted_answer_id.TrueEquals((int?) obj.accepted_answer_id) && + answer_count.TrueEquals((int?) obj.answer_count) && + answers.TrueEqualsListDynamic((IEnumerable) obj.answers) && + body.TrueEqualsString((string) obj.body) && + body_markdown.TrueEqualsString((string) obj.body_markdown) && + bounty_amount.TrueEquals((int?) obj.bounty_amount) && + bounty_closes_date.TrueEquals((DateTime?) obj.bounty_closes_date) && + close_vote_count.TrueEquals((int?) obj.close_vote_count) && + closed_date.TrueEquals((DateTime?) obj.closed_date) && + (closed_details == null && obj.closed_details == null || + closed_details.EqualsDynamic(obj.closed_details)) && + closed_reason.TrueEqualsString((string) obj.closed_reason) && + comment_count.TrueEquals((int?) obj.comment_count) && + comments.TrueEqualsListDynamic((IEnumerable) obj.comments) && + community_owned_date.TrueEquals((DateTime?) obj.community_owned_date) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + delete_vote_count.TrueEquals((int?) obj.delete_vote_count) && + down_vote_count.TrueEquals((int?) obj.down_vote_count) && + downvoted.TrueEquals((bool?) obj.downvoted) && + favorite_count.TrueEquals((int?) obj.favorite_count) && + favorited.TrueEquals((bool?) obj.favorited) && + is_answered.TrueEquals((bool?) obj.is_answered) && + last_activity_date.TrueEquals((DateTime?) obj.last_activity_date) && + last_edit_date.TrueEquals((DateTime?) obj.last_edit_date) && + (last_editor == null && obj.last_editor == null || last_editor.EqualsDynamic(obj.last_editor)) && + link.TrueEqualsString((string) obj.link) && + locked_date.TrueEquals((DateTime?) obj.locked_date) && + (migrated_from == null && obj.migrated_from == null || + migrated_from.EqualsDynamic(obj.migrated_from)) && + (migrated_to == null && obj.migrated_to == null || migrated_to.EqualsDynamic(obj.migrated_to)) && + (notice == null && obj.notice == null || notice.EqualsDynamic(obj.notice)) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + protected_date.TrueEquals((DateTime?) obj.protected_date) && + question_id.TrueEquals((int?) obj.question_id) && + reopen_vote_count.TrueEquals((int?) obj.reopen_vote_count) && + score.TrueEquals((int?) obj.score) && + share_link.TrueEqualsString((string) obj.share_link) && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title.TrueEqualsString((string) obj.title) && + up_vote_count.TrueEquals((int?) obj.up_vote_count) && + upvoted.TrueEquals((bool?) obj.upvoted) && + view_count.TrueEquals((int?) obj.view_count); + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class ClosedDetails : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public bool? on_hold { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string reason { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string description { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public List by_users { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public List original_questions { get; set; } + + public bool Equals(ClosedDetails obj) + { + return + by_users.TrueEqualsList(obj.by_users) && + description.TrueEqualsString(obj.description) && + on_hold.TrueEquals(obj.on_hold) && + original_questions.TrueEqualsList(obj.original_questions) && + reason.TrueEqualsString(obj.reason); + } + + public bool EqualsDynamic(dynamic obj) + { + var oq = obj.original_questions; + var oqI = (IEnumerable) oq; + + return + by_users.TrueEqualsListDynamic((IEnumerable) obj.by_users) && + description.TrueEqualsString((string) obj.description) && + on_hold.TrueEquals((bool?) obj.on_hold) && + //this.original_questions.TrueEqualsListDynamic((IEnumerable)obj.original_questions) && + original_questions.TrueEqualsListDynamic(oqI) && + reason.TrueEqualsString((string) obj.reason); + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class OriginalQuestion : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? accepted_answer_id { get; set; } + + public bool Equals(OriginalQuestion obj) + { + return + accepted_answer_id.TrueEquals(obj.accepted_answer_id) && + answer_count.TrueEquals(obj.answer_count) && + question_id.TrueEquals(obj.question_id) && + title.TrueEqualsString(obj.title); + } + + public bool EqualsDynamic(dynamic obj) + { + return + accepted_answer_id.TrueEquals((int?) obj.accepted_answer_id) && + answer_count.TrueEquals((int?) obj.answer_count) && + question_id.TrueEquals((int?) obj.question_id) && + title.TrueEqualsString((string) obj.title); + } + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Notice : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? owner_user_id { get; set; } + + public bool Equals(Notice obj) + { + return + body.TrueEqualsString(obj.body) && + creation_date.TrueEquals(obj.creation_date) && + owner_user_id.TrueEquals(obj.owner_user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + owner_user_id.TrueEquals((int?) obj.owner_user_id); + } + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class MigrationInfo : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public Info.Site other_site { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? on_date { get; set; } + + public bool Equals(MigrationInfo obj) + { + return + on_date.TrueEquals(obj.on_date) && + other_site.TrueEquals(obj.other_site) && + question_id.TrueEquals(obj.question_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + on_date.TrueEquals((DateTime?) obj.on_date) && + (other_site == null && obj.other_site == null || other_site.EqualsDynamic(obj.other_site)) && + question_id.TrueEquals((int?) obj.question_id); + } + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs b/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs new file mode 100644 index 00000000..186d5a1e --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/QuestionTimeline.cs @@ -0,0 +1,83 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum QuestionTimelineAction : byte + { + question = 1, + answer = 2, + comment = 3, + unaccepted_answer = 4, + accepted_answer = 5, + vote_aggregate = 6, + revision = 7, + post_state_changed = 8 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class QuestionTimeline : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public QuestionTimelineAction? timeline_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? comment_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string revision_guid { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? up_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? down_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public ShallowUser user { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public ShallowUser owner { get; set; } + + public bool Equals(QuestionTimeline obj) + { + return + comment_id.TrueEquals(obj.comment_id) && + creation_date.TrueEquals(obj.creation_date) && + down_vote_count.TrueEquals(obj.down_vote_count) && + owner.TrueEquals(obj.owner) && + post_id.TrueEquals(obj.post_id) && + question_id.TrueEquals(obj.question_id) && + revision_guid.TrueEqualsString(obj.revision_guid) && + timeline_type.TrueEquals(obj.timeline_type) && + up_vote_count.TrueEquals(obj.up_vote_count) && + user.TrueEquals(obj.user); + } + + public bool EqualsDynamic(dynamic obj) + { + return + comment_id.TrueEquals((int?) obj.comment_id) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + down_vote_count.TrueEquals((int?) obj.down_vote_count) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + post_id.TrueEquals((int?) obj.post_id) && + question_id.TrueEquals((int?) obj.question_id) && + revision_guid.TrueEqualsString((string) obj.revision_guid) && + timeline_type.TrueEquals((QuestionTimelineAction?) obj.timeline_type) && + up_vote_count.TrueEquals((int?) obj.up_vote_count) && + (user == null && obj.user == null || user.EqualsDynamic(obj.user)); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Reputation.cs b/benchmark/SerializerBenchmark/Models/Reputation.cs new file mode 100644 index 00000000..8b00d8dd --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Reputation.cs @@ -0,0 +1,72 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum VoteType : byte + { + up_votes = 2, + down_votes = 3, + spam = 12, + accepts = 1, + bounties_won = 9, + bounties_offered = 8, + suggested_edits = 16 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Reputation : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public VoteType? vote_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? reputation_change { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public DateTime? on_date { get; set; } + + public bool Equals(Reputation obj) + { + return + link.TrueEqualsString(obj.link) && + on_date.TrueEquals(obj.on_date) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + reputation_change.TrueEquals(obj.reputation_change) && + title.TrueEqualsString(obj.title) && + user_id.TrueEquals(obj.user_id) && + vote_type.TrueEquals(obj.vote_type); + } + + public bool EqualsDynamic(dynamic obj) + { + return + link.TrueEqualsString((string) obj.link) && + on_date.TrueEquals((DateTime?) obj.on_date) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + reputation_change.TrueEquals((int?) obj.reputation_change) && + title.TrueEqualsString((string) obj.title) && + user_id.TrueEquals((int?) obj.user_id) && + vote_type.TrueEquals((VoteType?) obj.vote_type); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/ReputationHistory.cs b/benchmark/SerializerBenchmark/Models/ReputationHistory.cs new file mode 100644 index 00000000..9f57aa01 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/ReputationHistory.cs @@ -0,0 +1,83 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class ReputationHistory : IGenericEquality + { + public enum ReputationHistoryType : byte + { + asker_accepts_answer = 1, + asker_unaccept_answer = 2, + answer_accepted = 3, + answer_unaccepted = 4, + + voter_downvotes = 5, + voter_undownvotes = 6, + post_downvoted = 7, + post_undownvoted = 8, + + post_upvoted = 9, + post_unupvoted = 10, + + suggested_edit_approval_received = 11, + + post_flagged_as_spam = 12, + post_flagged_as_offensive = 13, + + bounty_given = 14, + bounty_earned = 15, + bounty_cancelled = 16, + + post_deleted = 17, + post_undeleted = 18, + + association_bonus = 19, + arbitrary_reputation_change = 20, + + vote_fraud_reversal = 21, + + post_migrated = 22, + + user_deleted = 23 + } + + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? reputation_change { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public ReputationHistoryType? reputation_history_type { get; set; } + + public bool Equals(ReputationHistory obj) + { + return + creation_date.TrueEquals(obj.creation_date) && + post_id.TrueEquals(obj.post_id) && + reputation_change.TrueEquals(obj.reputation_change) && + reputation_history_type.TrueEquals(obj.reputation_history_type) && + user_id.TrueEquals(obj.user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + creation_date.TrueEquals((DateTime?) obj.creation_date) && + post_id.TrueEquals((int?) obj.post_id) && + reputation_change.TrueEquals((int?) obj.reputation_change) && + reputation_history_type.TrueEquals((ReputationHistoryType?) obj.reputation_history_type) && + user_id.TrueEquals((int?) obj.user_id); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Revision.cs b/benchmark/SerializerBenchmark/Models/Revision.cs new file mode 100644 index 00000000..f4d62d34 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Revision.cs @@ -0,0 +1,108 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum RevisionType : byte + { + single_user = 1, + vote_based = 2 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Revision : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string revision_guid { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? revision_number { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public RevisionType? revision_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string comment { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public bool? is_rollback { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public string last_body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string last_title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public List last_tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public bool? set_community_wiki { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public ShallowUser user { get; set; } + + public bool Equals(Revision obj) + { + return + body.TrueEqualsString(obj.body) && + comment.TrueEqualsString(obj.comment) && + creation_date.TrueEquals(obj.creation_date) && + is_rollback.TrueEquals(obj.is_rollback) && + last_body.TrueEqualsString(obj.last_body) && + last_tags.TrueEqualsString(obj.last_tags) && + last_title.TrueEqualsString(obj.last_title) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + revision_guid.TrueEqualsString(obj.revision_guid) && + revision_number.TrueEquals(obj.revision_number) && + revision_type.TrueEquals(obj.revision_type) && + set_community_wiki.TrueEquals(obj.set_community_wiki) && + tags.TrueEqualsString(obj.tags) && + title.TrueEqualsString(obj.title) && + user.TrueEquals(obj.user); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + comment.TrueEqualsString((string) obj.comment) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + is_rollback.TrueEquals((bool?) obj.is_rollback) && + last_body.TrueEqualsString((string) obj.last_body) && + last_tags.TrueEqualsString((IEnumerable) obj.last_tags) && + last_title.TrueEqualsString((string) obj.last_title) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + revision_guid.TrueEqualsString((string) obj.revision_guid) && + revision_number.TrueEquals((int?) obj.revision_number) && + revision_type.TrueEquals((RevisionType?) obj.revision_type) && + set_community_wiki.TrueEquals((bool?) obj.set_community_wiki) && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title.TrueEqualsString((string) obj.title) && + (user == null && obj.user == null || user.EqualsDynamic(obj.user)); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs b/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs new file mode 100644 index 00000000..85912ba5 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/SearchExcerpt.cs @@ -0,0 +1,119 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum SearchExcerptItemType : byte + { + question = 1, + answer = 2 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class SearchExcerpt : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string excerpt { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? community_owned_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public DateTime? locked_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public DateTime? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public ShallowUser owner { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public ShallowUser last_activity_user { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public SearchExcerptItemType? item_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public int? question_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public bool? is_answered { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public DateTime? closed_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public int? answer_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public bool? is_accepted { get; set; } + + public bool Equals(SearchExcerpt obj) + { + return + answer_count.TrueEquals(obj.answer_count) && + answer_id.TrueEquals(obj.answer_id) && + body.TrueEqualsString(obj.body) && + closed_date.TrueEquals(obj.closed_date) && + community_owned_date.TrueEquals(obj.community_owned_date) && + creation_date.TrueEquals(obj.creation_date) && + excerpt.TrueEqualsString(obj.excerpt) && + is_accepted.TrueEquals(obj.is_accepted) && + is_answered.TrueEquals(obj.is_answered) && + item_type.TrueEquals(obj.item_type) && + last_activity_date.TrueEquals(obj.last_activity_date) && + last_activity_user.TrueEquals(obj.last_activity_user) && + locked_date.TrueEquals(obj.locked_date) && + owner.TrueEquals(obj.owner) && + question_id.TrueEquals(obj.question_id) && + score.TrueEquals(obj.score) && + tags.TrueEqualsString(obj.tags) && + title.TrueEqualsString(obj.title); + } + + public bool EqualsDynamic(dynamic obj) + { + return + answer_count.TrueEquals((int?) obj.answer_count) && + answer_id.TrueEquals((int?) obj.answer_id) && + body.TrueEqualsString((string) obj.body) && + closed_date.TrueEquals((DateTime?) obj.closed_date) && + community_owned_date.TrueEquals((DateTime?) obj.community_owned_date) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + excerpt.TrueEqualsString((string) obj.excerpt) && + is_accepted.TrueEquals((bool?) obj.is_accepted) && + is_answered.TrueEquals((bool?) obj.is_answered) && + item_type.TrueEquals((SearchExcerptItemType?) obj.item_type) && + last_activity_date.TrueEquals((DateTime?) obj.last_activity_date) && + (last_activity_user == null && obj.last_activity_user == null || + last_activity_user.EqualsDynamic(obj.last_activity_user)) && + locked_date.TrueEquals((DateTime?) obj.locked_date) && + (owner == null && obj.owner == null || owner.EqualsDynamic(obj.owner)) && + question_id.TrueEquals((int?) obj.question_id) && + score.TrueEquals((int?) obj.score) && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title.TrueEqualsString((string) obj.title); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/ShallowUser.cs b/benchmark/SerializerBenchmark/Models/ShallowUser.cs new file mode 100644 index 00000000..2a5da846 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/ShallowUser.cs @@ -0,0 +1,68 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum UserType : byte + { + unregistered = 2, + registered = 3, + moderator = 4, + does_not_exist = 255 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class ShallowUser : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string display_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? reputation { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public UserType? user_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string profile_image { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? accept_rate { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public User.BadgeCount badge_counts { get; set; } + + public bool Equals(ShallowUser obj) + { + return + accept_rate.TrueEquals(obj.accept_rate) && + badge_counts.TrueEquals(obj.badge_counts) && + display_name.TrueEqualsString(obj.display_name) && + link.TrueEqualsString(obj.link) && + profile_image.TrueEqualsString(obj.profile_image) && + reputation.TrueEquals(obj.reputation) && + user_id.TrueEquals(obj.user_id) && + user_type.TrueEquals(obj.user_type); + } + + public bool EqualsDynamic(dynamic obj) + { + return + accept_rate.TrueEquals((int?) obj.accept_rate) && + (badge_counts == null && obj.badge_counts == null || badge_counts.EqualsDynamic(obj.badge_counts)) && + display_name.TrueEqualsString((string) obj.display_name) && + link.TrueEqualsString((string) obj.link) && + profile_image.TrueEqualsString((string) obj.profile_image) && + reputation.TrueEquals((int?) obj.reputation) && + user_id.TrueEquals((int?) obj.user_id) && + user_type.TrueEquals((UserType?) obj.user_type); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs b/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs new file mode 100644 index 00000000..79e6bac4 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/SuggestedEdit.cs @@ -0,0 +1,78 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class SuggestedEdit : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? suggested_edit_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public List tags { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public string comment { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public DateTime? approval_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public DateTime? rejection_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public ShallowUser proposing_user { get; set; } + + public bool Equals(SuggestedEdit obj) + { + return + approval_date.TrueEquals(obj.approval_date) && + body.TrueEqualsString(obj.body) && + comment.TrueEqualsString(obj.comment) && + creation_date.TrueEquals(obj.creation_date) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + proposing_user.TrueEquals(obj.proposing_user) && + rejection_date.TrueEquals(obj.rejection_date) && + suggested_edit_id.TrueEquals(obj.suggested_edit_id) && + tags.TrueEqualsString(obj.tags) && + title.TrueEqualsString(obj.title); + } + + public bool EqualsDynamic(dynamic obj) + { + return + approval_date.TrueEquals((DateTime?) obj.approval_date) && + body.TrueEqualsString((string) obj.body) && + comment.TrueEqualsString((string) obj.comment) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + (proposing_user == null && obj.proposing_user == null || + proposing_user.EqualsDynamic(obj.proposing_user)) && + rejection_date.TrueEquals((DateTime?) obj.rejection_date) && + suggested_edit_id.TrueEquals((int?) obj.suggested_edit_id) && + tags.TrueEqualsString((IEnumerable) obj.tags) && + title.TrueEqualsString((string) obj.title); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/Tag.cs b/benchmark/SerializerBenchmark/Models/Tag.cs new file mode 100644 index 00000000..9ac7fd29 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/Tag.cs @@ -0,0 +1,62 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using System.Collections.Generic; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class Tag : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public bool? is_required { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public bool? is_moderator_only { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public bool? has_synonyms { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public DateTime? last_activity_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public List synonyms { get; set; } + + public bool Equals(Tag obj) + { + return + count.TrueEquals(obj.count) && + has_synonyms.TrueEquals(obj.has_synonyms) && + is_moderator_only.TrueEquals(obj.is_moderator_only) && + is_required.TrueEquals(obj.is_required) && + last_activity_date.TrueEquals(obj.last_activity_date) && + name.TrueEqualsString(obj.name) && + synonyms.TrueEqualsString(obj.synonyms) && + user_id.TrueEquals(obj.user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + count.TrueEquals((int?) obj.count) && + has_synonyms.TrueEquals((bool?) obj.has_synonyms) && + is_moderator_only.TrueEquals((bool?) obj.is_moderator_only) && + is_required.TrueEquals((bool?) obj.is_required) && + last_activity_date.TrueEquals((DateTime?) obj.last_activity_date) && + name.TrueEqualsString((string) obj.name) && + synonyms.TrueEqualsString((IEnumerable) obj.synonyms) && + user_id.TrueEquals((int?) obj.user_id); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/TagScore.cs b/benchmark/SerializerBenchmark/Models/TagScore.cs new file mode 100644 index 00000000..7aee2fc8 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/TagScore.cs @@ -0,0 +1,35 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class TagScore : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public ShallowUser user { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? post_count { get; set; } + + public bool Equals(TagScore obj) + { + return + post_count.TrueEquals(obj.post_count) && + score.TrueEquals(obj.score) && + user.TrueEquals(obj.user); + } + + public bool EqualsDynamic(dynamic obj) + { + return + post_count.TrueEquals((int?) obj.post_count) && + score.TrueEquals((int?) obj.score) && + (user == null && obj.user == null || user.EqualsDynamic(obj.user)); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/TagSynonym.cs b/benchmark/SerializerBenchmark/Models/TagSynonym.cs new file mode 100644 index 00000000..786d027b --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/TagSynonym.cs @@ -0,0 +1,46 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class TagSynonym : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string from_tag { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string to_tag { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? applied_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public DateTime? last_applied_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? creation_date { get; set; } + + public bool Equals(TagSynonym obj) + { + return + applied_count.TrueEquals(obj.applied_count) && + creation_date.TrueEquals(obj.creation_date) && + from_tag.TrueEqualsString(obj.from_tag) && + last_applied_date.TrueEquals(obj.last_applied_date) && + to_tag.TrueEqualsString(obj.to_tag); + } + + public bool EqualsDynamic(dynamic obj) + { + return + applied_count.TrueEquals((int?) obj.applied_count) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + from_tag.TrueEqualsString((string) obj.from_tag) && + last_applied_date.TrueEquals((DateTime?) obj.last_applied_date) && + to_tag.TrueEqualsString((string) obj.to_tag); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/TagWiki.cs b/benchmark/SerializerBenchmark/Models/TagWiki.cs new file mode 100644 index 00000000..d5804d14 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/TagWiki.cs @@ -0,0 +1,58 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class TagWiki : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string tag_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string body { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public string excerpt { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public DateTime? body_last_edit_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public DateTime? excerpt_last_edit_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public ShallowUser last_body_editor { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public ShallowUser last_excerpt_editor { get; set; } + + public bool Equals(TagWiki obj) + { + return + body.TrueEqualsString(obj.body) && + body_last_edit_date.TrueEquals(obj.body_last_edit_date) && + excerpt.TrueEqualsString(obj.excerpt) && + excerpt_last_edit_date.TrueEquals(obj.excerpt_last_edit_date) && + last_body_editor.TrueEquals(obj.last_body_editor) && + last_excerpt_editor.TrueEquals(obj.last_excerpt_editor) && + tag_name.TrueEqualsString(obj.tag_name); + } + + public bool EqualsDynamic(dynamic obj) + { + return + body.TrueEqualsString((string) obj.body) && + body_last_edit_date.TrueEquals((DateTime?) obj.body_last_edit_date) && + excerpt.TrueEqualsString((string) obj.excerpt) && + excerpt_last_edit_date.TrueEquals((DateTime?) obj.excerpt_last_edit_date) && + (last_body_editor == null && obj.last_body_editor == null || + last_body_editor.EqualsDynamic(obj.last_body_editor)) && + (last_excerpt_editor == null && obj.last_excerpt_editor == null || + last_excerpt_editor.EqualsDynamic(obj.last_excerpt_editor)) && + tag_name.TrueEqualsString((string) obj.tag_name); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/TopTag.cs b/benchmark/SerializerBenchmark/Models/TopTag.cs new file mode 100644 index 00000000..e8940a10 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/TopTag.cs @@ -0,0 +1,50 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class TopTag : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public string tag_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? question_score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? question_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? answer_score { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? user_id { get; set; } + + public bool Equals(TopTag obj) + { + return + answer_count.TrueEquals(obj.answer_count) && + answer_score.TrueEquals(obj.answer_score) && + question_count.TrueEquals(obj.question_count) && + question_score.TrueEquals(obj.question_score) && + tag_name.TrueEqualsString(obj.tag_name) && + user_id.TrueEquals(obj.user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + answer_count.TrueEquals((int?) obj.answer_count) && + answer_score.TrueEquals((int?) obj.answer_score) && + question_count.TrueEquals((int?) obj.question_count) && + question_score.TrueEquals((int?) obj.question_score) && + tag_name.TrueEqualsString((string) obj.tag_name) && + user_id.TrueEquals((int?) obj.user_id); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/User.cs b/benchmark/SerializerBenchmark/Models/User.cs new file mode 100644 index 00000000..b8bb8d42 --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/User.cs @@ -0,0 +1,190 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class User : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public UserType? user_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public string display_name { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public string profile_image { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? reputation { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? reputation_change_day { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public int? reputation_change_week { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public int? reputation_change_month { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public int? reputation_change_quarter { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public int? reputation_change_year { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(12), oldmsgpack::MessagePack.Key(12 - 1), newmsgpack::MessagePack.Key(12 - 1)] + public int? age { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(13), oldmsgpack::MessagePack.Key(13 - 1), newmsgpack::MessagePack.Key(13 - 1)] + public DateTime? last_access_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(14), oldmsgpack::MessagePack.Key(14 - 1), newmsgpack::MessagePack.Key(14 - 1)] + public DateTime? last_modified_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(15), oldmsgpack::MessagePack.Key(15 - 1), newmsgpack::MessagePack.Key(15 - 1)] + public bool? is_employee { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(16), oldmsgpack::MessagePack.Key(16 - 1), newmsgpack::MessagePack.Key(16 - 1)] + public string link { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(17), oldmsgpack::MessagePack.Key(17 - 1), newmsgpack::MessagePack.Key(17 - 1)] + public string website_url { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(18), oldmsgpack::MessagePack.Key(18 - 1), newmsgpack::MessagePack.Key(18 - 1)] + public string location { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(19), oldmsgpack::MessagePack.Key(19 - 1), newmsgpack::MessagePack.Key(19 - 1)] + public int? account_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(20), oldmsgpack::MessagePack.Key(20 - 1), newmsgpack::MessagePack.Key(20 - 1)] + public DateTime? timed_penalty_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(21), oldmsgpack::MessagePack.Key(21 - 1), newmsgpack::MessagePack.Key(21 - 1)] + public BadgeCount badge_counts { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(22), oldmsgpack::MessagePack.Key(22 - 1), newmsgpack::MessagePack.Key(22 - 1)] + public int? question_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(23), oldmsgpack::MessagePack.Key(23 - 1), newmsgpack::MessagePack.Key(23 - 1)] + public int? answer_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(24), oldmsgpack::MessagePack.Key(24 - 1), newmsgpack::MessagePack.Key(24 - 1)] + public int? up_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(25), oldmsgpack::MessagePack.Key(25 - 1), newmsgpack::MessagePack.Key(25 - 1)] + public int? down_vote_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(26), oldmsgpack::MessagePack.Key(26 - 1), newmsgpack::MessagePack.Key(26 - 1)] + public string about_me { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(27), oldmsgpack::MessagePack.Key(27 - 1), newmsgpack::MessagePack.Key(27 - 1)] + public int? view_count { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(28), oldmsgpack::MessagePack.Key(28 - 1), newmsgpack::MessagePack.Key(28 - 1)] + public int? accept_rate { get; set; } + + public bool Equals(User obj) + { + return + about_me.TrueEqualsString(obj.about_me) && + accept_rate.TrueEquals(obj.accept_rate) && + account_id.TrueEquals(obj.account_id) && + age.TrueEquals(obj.age) && + answer_count.TrueEquals(obj.answer_count) && + badge_counts.TrueEquals(obj.badge_counts) && + creation_date.TrueEquals(obj.creation_date) && + display_name.TrueEqualsString(obj.display_name) && + down_vote_count.TrueEquals(obj.down_vote_count) && + is_employee.TrueEquals(obj.is_employee) && + last_access_date.TrueEquals(obj.last_access_date) && + last_modified_date.TrueEquals(obj.last_modified_date) && + link.TrueEqualsString(obj.link) && + location.TrueEqualsString(obj.location) && + profile_image.TrueEqualsString(obj.profile_image) && + question_count.TrueEquals(obj.question_count) && + reputation.TrueEquals(obj.reputation) && + reputation_change_day.TrueEquals(obj.reputation_change_day) && + reputation_change_month.TrueEquals(obj.reputation_change_month) && + reputation_change_quarter.TrueEquals(obj.reputation_change_quarter) && + reputation_change_week.TrueEquals(obj.reputation_change_week) && + reputation_change_year.TrueEquals(obj.reputation_change_year) && + timed_penalty_date.TrueEquals(obj.timed_penalty_date) && + up_vote_count.TrueEquals(obj.up_vote_count) && + user_id.TrueEquals(obj.user_id) && + user_type.TrueEquals(obj.user_type) && + view_count.TrueEquals(obj.view_count) && + website_url.TrueEqualsString(obj.website_url); + } + + public bool EqualsDynamic(dynamic obj) + { + return + about_me.TrueEqualsString((string) obj.about_me) && + accept_rate.TrueEquals((int?) obj.accept_rate) && + account_id.TrueEquals((int?) obj.account_id) && + age.TrueEquals((int?) obj.age) && + answer_count.TrueEquals((int?) obj.answer_count) && + (badge_counts == null && obj.badge_counts == null || badge_counts.EqualsDynamic(obj.badge_counts)) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + display_name.TrueEqualsString((string) obj.display_name) && + down_vote_count.TrueEquals((int?) obj.down_vote_count) && + is_employee.TrueEquals((bool?) obj.is_employee) && + last_access_date.TrueEquals((DateTime?) obj.last_access_date) && + last_modified_date.TrueEquals((DateTime?) obj.last_modified_date) && + link.TrueEqualsString((string) obj.link) && + location.TrueEqualsString((string) obj.location) && + profile_image.TrueEqualsString((string) obj.profile_image) && + question_count.TrueEquals((int?) obj.question_count) && + reputation.TrueEquals((int?) obj.reputation) && + reputation_change_day.TrueEquals((int?) obj.reputation_change_day) && + reputation_change_month.TrueEquals((int?) obj.reputation_change_month) && + reputation_change_quarter.TrueEquals((int?) obj.reputation_change_quarter) && + reputation_change_week.TrueEquals((int?) obj.reputation_change_week) && + reputation_change_year.TrueEquals((int?) obj.reputation_change_year) && + timed_penalty_date.TrueEquals((DateTime?) obj.timed_penalty_date) && + up_vote_count.TrueEquals((int?) obj.up_vote_count) && + user_id.TrueEquals((int?) obj.user_id) && + user_type.TrueEquals((UserType?) obj.user_type) && + view_count.TrueEquals((int?) obj.view_count) && + website_url.TrueEqualsString((string) obj.website_url); + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class BadgeCount : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? gold { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public int? silver { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public int? bronze { get; set; } + + public bool Equals(BadgeCount obj) + { + return + bronze.TrueEquals(obj.bronze) && + silver.TrueEquals(obj.silver) && + gold.TrueEquals(obj.gold); + } + + public bool EqualsDynamic(dynamic obj) + { + return + bronze.TrueEquals((int?) obj.bronze) && + silver.TrueEquals((int?) obj.silver) && + gold.TrueEquals((int?) obj.gold); + } + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/UserTimeline.cs b/benchmark/SerializerBenchmark/Models/UserTimeline.cs new file mode 100644 index 00000000..d973c64b --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/UserTimeline.cs @@ -0,0 +1,88 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using System; +using ProtoBuf; + +namespace Benchmark.Models +{ + public enum UserTimelineType : byte + { + commented = 1, + asked = 2, + answered = 3, + badge = 4, + revision = 5, + accepted = 6, + reviewed = 7, + suggested = 8 + } + + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class UserTimeline : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public DateTime? creation_date { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public PostType? post_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public UserTimelineType? timeline_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public int? post_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? comment_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? suggested_edit_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(8), oldmsgpack::MessagePack.Key(8 - 1), newmsgpack::MessagePack.Key(8 - 1)] + public int? badge_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(9), oldmsgpack::MessagePack.Key(9 - 1), newmsgpack::MessagePack.Key(9 - 1)] + public string title { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(10), oldmsgpack::MessagePack.Key(10 - 1), newmsgpack::MessagePack.Key(10 - 1)] + public string detail { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(11), oldmsgpack::MessagePack.Key(11 - 1), newmsgpack::MessagePack.Key(11 - 1)] + public string link { get; set; } + + public bool Equals(UserTimeline obj) + { + return + badge_id.TrueEquals(obj.badge_id) && + comment_id.TrueEquals(obj.comment_id) && + creation_date.TrueEquals(obj.creation_date) && + detail.TrueEqualsString(obj.detail) && + link.TrueEqualsString(obj.link) && + post_id.TrueEquals(obj.post_id) && + post_type.TrueEquals(obj.post_type) && + suggested_edit_id.TrueEquals(obj.suggested_edit_id) && + timeline_type.TrueEquals(obj.timeline_type) && + title.TrueEqualsString(obj.title) && + user_id.TrueEquals(obj.user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + badge_id.TrueEquals((int?) obj.badge_id) && + comment_id.TrueEquals((int?) obj.comment_id) && + creation_date.TrueEquals((DateTime?) obj.creation_date) && + detail.TrueEqualsString((string) obj.detail) && + link.TrueEqualsString((string) obj.link) && + post_id.TrueEquals((int?) obj.post_id) && + post_type.TrueEquals((PostType?) obj.post_type) && + suggested_edit_id.TrueEquals((int?) obj.suggested_edit_id) && + timeline_type.TrueEquals((UserTimelineType?) obj.timeline_type) && + title.TrueEqualsString((string) obj.title) && + user_id.TrueEquals((int?) obj.user_id); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Models/WritePermission.cs b/benchmark/SerializerBenchmark/Models/WritePermission.cs new file mode 100644 index 00000000..7799a32d --- /dev/null +++ b/benchmark/SerializerBenchmark/Models/WritePermission.cs @@ -0,0 +1,55 @@ +extern alias oldmsgpack; +extern alias newmsgpack; +using ProtoBuf; + +namespace Benchmark.Models +{ + [ProtoContract, System.Serializable, System.Runtime.Serialization.DataContract, oldmsgpack::MessagePack.MessagePackObject, newmsgpack::MessagePack.MessagePackObject] + public class WritePermission : IGenericEquality + { + [System.Runtime.Serialization.DataMember(), ProtoMember(1), oldmsgpack::MessagePack.Key(1 - 1), newmsgpack::MessagePack.Key(1 - 1)] + public int? user_id { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(2), oldmsgpack::MessagePack.Key(2 - 1), newmsgpack::MessagePack.Key(2 - 1)] + public string object_type { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(3), oldmsgpack::MessagePack.Key(3 - 1), newmsgpack::MessagePack.Key(3 - 1)] + public bool? can_add { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(4), oldmsgpack::MessagePack.Key(4 - 1), newmsgpack::MessagePack.Key(4 - 1)] + public bool? can_edit { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(5), oldmsgpack::MessagePack.Key(5 - 1), newmsgpack::MessagePack.Key(5 - 1)] + public bool? can_delete { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(6), oldmsgpack::MessagePack.Key(6 - 1), newmsgpack::MessagePack.Key(6 - 1)] + public int? max_daily_actions { get; set; } + + [System.Runtime.Serialization.DataMember(), ProtoMember(7), oldmsgpack::MessagePack.Key(7 - 1), newmsgpack::MessagePack.Key(7 - 1)] + public int? min_seconds_between_actions { get; set; } + + public bool Equals(WritePermission obj) + { + return + can_add.TrueEquals(obj.can_add) && + can_delete.TrueEquals(obj.can_delete) && + can_edit.TrueEquals(obj.can_edit) && + max_daily_actions.TrueEquals(obj.max_daily_actions) && + min_seconds_between_actions.TrueEquals(obj.min_seconds_between_actions) && + object_type.TrueEqualsString(obj.object_type) && + user_id.TrueEquals(obj.user_id); + } + + public bool EqualsDynamic(dynamic obj) + { + return + can_add.TrueEquals((bool?) obj.can_add) && + can_delete.TrueEquals((bool?) obj.can_delete) && + can_edit.TrueEquals((bool?) obj.can_edit) && + max_daily_actions.TrueEquals((int?) obj.max_daily_actions) && + min_seconds_between_actions.TrueEquals((int?) obj.min_seconds_between_actions) && + object_type.TrueEqualsString((string) obj.object_type) && + user_id.TrueEquals((int?) obj.user_id); + } + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Program.cs b/benchmark/SerializerBenchmark/Program.cs new file mode 100644 index 00000000..73b95297 --- /dev/null +++ b/benchmark/SerializerBenchmark/Program.cs @@ -0,0 +1,13 @@ +using Benchmark; +using BenchmarkDotNet.Running; + +namespace ConsoleApp1 +{ + class Program + { + static void Main(string[] args) + { + BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); + } + } +} diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.cs b/benchmark/SerializerBenchmark/SerializerBenchmark.cs new file mode 100644 index 00000000..8f1a7f03 --- /dev/null +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.cs @@ -0,0 +1,953 @@ +namespace Benchmark +{ + using Benchmark.Fixture; + using Benchmark.Models; + using Benchmark.Serializers; + using BenchmarkDotNet.Attributes; + using System; + using System.Collections.Generic; + + [Config(typeof(BenchmarkConfig))] + public class AllSerializerBenchmark_BytesInOut + { + [ParamsSource(nameof(Serializers))] + public SerializerBase Serializer; + + // Currently BenchmarkdDotNet does not detect inherited ParamsSource so use copy and paste:) + + public IEnumerable Serializers => new SerializerBase[] + { + new MsgPack_v1(), + new MsgPack_v2(), + new MsgPackLz4_v1(), + new MsgPackLz4_v2(), + new Protobuf(), + new JsonNet(), + new BinaryFormatter_(), + new DataContract_(), + new Hyperion_(), + new Jil_(), + new SpanJson_(), + new Utf8Json_(), + new MsgPackCli(), + new FsPickler_() + }; + + protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); + + // primitives + + protected static readonly sbyte SByteInput = ExpressionTreeFixture.Create(); + protected static readonly short ShortInput = ExpressionTreeFixture.Create(); + protected static readonly int IntInput = ExpressionTreeFixture.Create(); + protected static readonly long LongInput = ExpressionTreeFixture.Create(); + protected static readonly byte ByteInput = ExpressionTreeFixture.Create(); + protected static readonly ushort UShortInput = ExpressionTreeFixture.Create(); + protected static readonly uint UIntInput = ExpressionTreeFixture.Create(); + protected static readonly ulong ULongInput = ExpressionTreeFixture.Create(); + protected static readonly bool BoolInput = ExpressionTreeFixture.Create(); + protected static readonly string StringInput = ExpressionTreeFixture.Create(); + protected static readonly char CharInput = ExpressionTreeFixture.Create(); + protected static readonly DateTime DateTimeInput = ExpressionTreeFixture.Create(); + protected static readonly Guid GuidInput = ExpressionTreeFixture.Create(); + protected static readonly byte[] BytesInput = ExpressionTreeFixture.Create(); + + // models + + protected static readonly Benchmark.Models.AccessToken AccessTokenInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.AccountMerge AccountMergeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Answer AnswerInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Badge BadgeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Comment CommentInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Error ErrorInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Event EventInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileFeed MobileFeedInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileQuestion MobileQuestionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileRepChange MobileRepChangeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileInboxItem MobileInboxItemInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBadgeAward MobileBadgeAwardInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobilePrivilege MobilePrivilegeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileCommunityBulletin MobileCommunityBulletinInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileAssociationBonus MobileAssociationBonusInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileCareersJobAd MobileCareersJobAdInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBannerAd MobileBannerAdInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileUpdateNotice MobileUpdateNoticeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.FlagOption FlagOptionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.InboxItem InboxItemInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info InfoInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.NetworkUser NetworkUserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Notification NotificationInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Post PostInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Privilege PrivilegeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question QuestionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.QuestionTimeline QuestionTimelineInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Reputation ReputationInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.ReputationHistory ReputationHistoryInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Revision RevisionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.SearchExcerpt SearchExcerptInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.ShallowUser ShallowUserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.SuggestedEdit SuggestedEditInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Tag TagInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagScore TagScoreInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagSynonym TagSynonymInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagWiki TagWikiInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TopTag TopTagInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.User UserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.UserTimeline UserTimelineInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.WritePermission WritePermissionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBannerAd.MobileBannerAdImage MobileBannerAdImageInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.Site SiteInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.RelatedSite RelatedSiteInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.ClosedDetails ClosedDetailsInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.Notice NoticeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.MigrationInfo MigrationInfoInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.User.BadgeCount BadgeCountInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.Site.Styling StylingInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.ClosedDetails.OriginalQuestion OriginalQuestionInput = ExpressionTreeFixture.Create(); + + object SByteOutput; + object ShortOutput; + object IntOutput; + object LongOutput; + object ByteOutput; + object UShortOutput; + object UIntOutput; + object ULongOutput; + object BoolOutput; + object StringOutput; + object CharOutput; + object DateTimeOutput; + object GuidOutput; + object BytesOutput; + + object AccessTokenOutput; + object AccountMergeOutput; + object AnswerOutput; + object BadgeOutput; + object CommentOutput; + object ErrorOutput; + object EventOutput; + object MobileFeedOutput; + object MobileQuestionOutput; + object MobileRepChangeOutput; + object MobileInboxItemOutput; + object MobileBadgeAwardOutput; + object MobilePrivilegeOutput; + object MobileCommunityBulletinOutput; + object MobileAssociationBonusOutput; + object MobileCareersJobAdOutput; + object MobileBannerAdOutput; + object MobileUpdateNoticeOutput; + object FlagOptionOutput; + object InboxItemOutput; + object InfoOutput; + object NetworkUserOutput; + object NotificationOutput; + object PostOutput; + object PrivilegeOutput; + object QuestionOutput; + object QuestionTimelineOutput; + object ReputationOutput; + object ReputationHistoryOutput; + object RevisionOutput; + object SearchExcerptOutput; + object ShallowUserOutput; + object SuggestedEditOutput; + object TagOutput; + object TagScoreOutput; + object TagSynonymOutput; + object TagWikiOutput; + object TopTagOutput; + object UserOutput; + object UserTimelineOutput; + object WritePermissionOutput; + object MobileBannerAdImageOutput; + object SiteOutput; + object RelatedSiteOutput; + object ClosedDetailsOutput; + object NoticeOutput; + object MigrationInfoOutput; + object BadgeCountOutput; + object StylingOutput; + object OriginalQuestionOutput; + + [GlobalSetup] + public void Setup() + { + // primitives + SByteOutput = Serializer.Serialize(SByteInput); + ShortOutput = Serializer.Serialize(ShortInput); + IntOutput = Serializer.Serialize(IntInput); + LongOutput = Serializer.Serialize(LongInput); + ByteOutput = Serializer.Serialize(ByteInput); + UShortOutput = Serializer.Serialize(UShortInput); + UIntOutput = Serializer.Serialize(UIntInput); + ULongOutput = Serializer.Serialize(ULongInput); + BoolOutput = Serializer.Serialize(BoolInput); + StringOutput = Serializer.Serialize(StringInput); + CharOutput = Serializer.Serialize(CharInput); + DateTimeOutput = Serializer.Serialize(DateTimeInput); + GuidOutput = Serializer.Serialize(GuidInput); + BytesOutput = Serializer.Serialize(BytesInput); + + // models + AccessTokenOutput = Serializer.Serialize(AccessTokenInput); + AccountMergeOutput = Serializer.Serialize(AccountMergeInput); + AnswerOutput = Serializer.Serialize(AnswerInput); + BadgeOutput = Serializer.Serialize(BadgeInput); + CommentOutput = Serializer.Serialize(CommentInput); + ErrorOutput = Serializer.Serialize(ErrorInput); + EventOutput = Serializer.Serialize(EventInput); + MobileFeedOutput = Serializer.Serialize(MobileFeedInput); + MobileQuestionOutput = Serializer.Serialize(MobileQuestionInput); + MobileRepChangeOutput = Serializer.Serialize(MobileRepChangeInput); + MobileInboxItemOutput = Serializer.Serialize(MobileInboxItemInput); + MobileBadgeAwardOutput = Serializer.Serialize(MobileBadgeAwardInput); + MobilePrivilegeOutput = Serializer.Serialize(MobilePrivilegeInput); + MobileCommunityBulletinOutput = Serializer.Serialize(MobileCommunityBulletinInput); + MobileAssociationBonusOutput = Serializer.Serialize(MobileAssociationBonusInput); + MobileCareersJobAdOutput = Serializer.Serialize(MobileCareersJobAdInput); + MobileBannerAdOutput = Serializer.Serialize(MobileBannerAdInput); + MobileUpdateNoticeOutput = Serializer.Serialize(MobileUpdateNoticeInput); + FlagOptionOutput = Serializer.Serialize(FlagOptionInput); + InboxItemOutput = Serializer.Serialize(InboxItemInput); + InfoOutput = Serializer.Serialize(InfoInput); + NetworkUserOutput = Serializer.Serialize(NetworkUserInput); + NotificationOutput = Serializer.Serialize(NotificationInput); + PostOutput = Serializer.Serialize(PostInput); + PrivilegeOutput = Serializer.Serialize(PrivilegeInput); + QuestionOutput = Serializer.Serialize(QuestionInput); + QuestionTimelineOutput = Serializer.Serialize(QuestionTimelineInput); + ReputationOutput = Serializer.Serialize(ReputationInput); + ReputationHistoryOutput = Serializer.Serialize(ReputationHistoryInput); + RevisionOutput = Serializer.Serialize(RevisionInput); + SearchExcerptOutput = Serializer.Serialize(SearchExcerptInput); + ShallowUserOutput = Serializer.Serialize(ShallowUserInput); + SuggestedEditOutput = Serializer.Serialize(SuggestedEditInput); + TagOutput = Serializer.Serialize(TagInput); + TagScoreOutput = Serializer.Serialize(TagScoreInput); + TagSynonymOutput = Serializer.Serialize(TagSynonymInput); + TagWikiOutput = Serializer.Serialize(TagWikiInput); + TopTagOutput = Serializer.Serialize(TopTagInput); + UserOutput = Serializer.Serialize(UserInput); + UserTimelineOutput = Serializer.Serialize(UserTimelineInput); + WritePermissionOutput = Serializer.Serialize(WritePermissionInput); + MobileBannerAdImageOutput = Serializer.Serialize(MobileBannerAdImageInput); + SiteOutput = Serializer.Serialize(SiteInput); + RelatedSiteOutput = Serializer.Serialize(RelatedSiteInput); + ClosedDetailsOutput = Serializer.Serialize(ClosedDetailsInput); + NoticeOutput = Serializer.Serialize(NoticeInput); + MigrationInfoOutput = Serializer.Serialize(MigrationInfoInput); + BadgeCountOutput = Serializer.Serialize(BadgeCountInput); + StylingOutput = Serializer.Serialize(StylingInput); + OriginalQuestionOutput = Serializer.Serialize(OriginalQuestionInput); + } + + // Serialize + + [Benchmark] public object _PrimitiveSByteSerialize() => Serializer.Serialize(SByteInput); + [Benchmark] public object _PrimitiveShortSerialize() => Serializer.Serialize(ShortInput); + [Benchmark] public object _PrimitiveIntSerialize() => Serializer.Serialize(IntInput); + [Benchmark] public object _PrimitiveLongSerialize() => Serializer.Serialize(LongInput); + [Benchmark] public object _PrimitiveByteSerialize() => Serializer.Serialize(ByteInput); + [Benchmark] public object _PrimitiveUShortSerialize() => Serializer.Serialize(UShortInput); + [Benchmark] public object _PrimitiveUIntSerialize() => Serializer.Serialize(UIntInput); + [Benchmark] public object _PrimitiveULongSerialize() => Serializer.Serialize(ULongInput); + [Benchmark] public object _PrimitiveBoolSerialize() => Serializer.Serialize(BoolInput); + [Benchmark] public object _PrimitiveStringSerialize() => Serializer.Serialize(StringInput); + [Benchmark] public object _PrimitiveCharSerialize() => Serializer.Serialize(CharInput); + [Benchmark] public object _PrimitiveDateTimeSerialize() => Serializer.Serialize(DateTimeInput); + [Benchmark] public object _PrimitiveGuidSerialize() => Serializer.Serialize(GuidInput); + [Benchmark] public object _PrimitiveBytesSerialize() => Serializer.Serialize(BytesInput); + + [Benchmark] public object AccessTokenSerialize() => Serializer.Serialize(AccessTokenInput); + [Benchmark] public object AccountMergeSerialize() => Serializer.Serialize(AccountMergeInput); + [Benchmark] public object AnswerSerialize() => Serializer.Serialize(AnswerInput); + [Benchmark] public object BadgeSerialize() => Serializer.Serialize(BadgeInput); + [Benchmark] public object CommentSerialize() => Serializer.Serialize(CommentInput); + [Benchmark] public object ErrorSerialize() => Serializer.Serialize(ErrorInput); + [Benchmark] public object EventSerialize() => Serializer.Serialize(EventInput); + [Benchmark] public object MobileFeedSerialize() => Serializer.Serialize(MobileFeedInput); + [Benchmark] public object MobileQuestionSerialize() => Serializer.Serialize(MobileQuestionInput); + [Benchmark] public object MobileRepChangeSerialize() => Serializer.Serialize(MobileRepChangeInput); + [Benchmark] public object MobileInboxItemSerialize() => Serializer.Serialize(MobileInboxItemInput); + [Benchmark] public object MobileBadgeAwardSerialize() => Serializer.Serialize(MobileBadgeAwardInput); + [Benchmark] public object MobilePrivilegeSerialize() => Serializer.Serialize(MobilePrivilegeInput); + [Benchmark] public object MobileCommunityBulletinSerialize() => Serializer.Serialize(MobileCommunityBulletinInput); + [Benchmark] public object MobileAssociationBonusSerialize() => Serializer.Serialize(MobileAssociationBonusInput); + [Benchmark] public object MobileCareersJobAdSerialize() => Serializer.Serialize(MobileCareersJobAdInput); + [Benchmark] public object MobileBannerAdSerialize() => Serializer.Serialize(MobileBannerAdInput); + [Benchmark] public object MobileUpdateNoticeSerialize() => Serializer.Serialize(MobileUpdateNoticeInput); + [Benchmark] public object FlagOptionSerialize() => Serializer.Serialize(FlagOptionInput); + [Benchmark] public object InboxItemSerialize() => Serializer.Serialize(InboxItemInput); + [Benchmark] public object InfoSerialize() => Serializer.Serialize(InfoInput); + [Benchmark] public object NetworkUserSerialize() => Serializer.Serialize(NetworkUserInput); + [Benchmark] public object NotificationSerialize() => Serializer.Serialize(NotificationInput); + [Benchmark] public object PostSerialize() => Serializer.Serialize(PostInput); + [Benchmark] public object PrivilegeSerialize() => Serializer.Serialize(PrivilegeInput); + [Benchmark] public object QuestionSerialize() => Serializer.Serialize(QuestionInput); + [Benchmark] public object QuestionTimelineSerialize() => Serializer.Serialize(QuestionTimelineInput); + [Benchmark] public object ReputationSerialize() => Serializer.Serialize(ReputationInput); + [Benchmark] public object ReputationHistorySerialize() => Serializer.Serialize(ReputationHistoryInput); + [Benchmark] public object RevisionSerialize() => Serializer.Serialize(RevisionInput); + [Benchmark] public object SearchExcerptSerialize() => Serializer.Serialize(SearchExcerptInput); + [Benchmark] public object ShallowUserSerialize() => Serializer.Serialize(ShallowUserInput); + [Benchmark] public object SuggestedEditSerialize() => Serializer.Serialize(SuggestedEditInput); + [Benchmark] public object TagSerialize() => Serializer.Serialize(TagInput); + [Benchmark] public object TagScoreSerialize() => Serializer.Serialize(TagScoreInput); + [Benchmark] public object TagSynonymSerialize() => Serializer.Serialize(TagSynonymInput); + [Benchmark] public object TagWikiSerialize() => Serializer.Serialize(TagWikiInput); + [Benchmark] public object TopTagSerialize() => Serializer.Serialize(TopTagInput); + [Benchmark] public object UserSerialize() => Serializer.Serialize(UserInput); + [Benchmark] public object UserTimelineSerialize() => Serializer.Serialize(UserTimelineInput); + [Benchmark] public object WritePermissionSerialize() => Serializer.Serialize(WritePermissionInput); + [Benchmark] public object MobileBannerAdImageSerialize() => Serializer.Serialize(MobileBannerAdImageInput); + [Benchmark] public object SiteSerialize() => Serializer.Serialize(SiteInput); + [Benchmark] public object RelatedSiteSerialize() => Serializer.Serialize(RelatedSiteInput); + [Benchmark] public object ClosedDetailsSerialize() => Serializer.Serialize(ClosedDetailsInput); + [Benchmark] public object NoticeSerialize() => Serializer.Serialize(NoticeInput); + [Benchmark] public object MigrationInfoSerialize() => Serializer.Serialize(MigrationInfoInput); + [Benchmark] public object BadgeCountSerialize() => Serializer.Serialize(BadgeCountInput); + [Benchmark] public object StylingSerialize() => Serializer.Serialize(StylingInput); + [Benchmark] public object OriginalQuestionSerialize() => Serializer.Serialize(OriginalQuestionInput); + + // Deserialize + + [Benchmark] public SByte _PrimitiveSByteDeserialize() => Serializer.Deserialize(SByteOutput); + [Benchmark] public short _PrimitiveShortDeserialize() => Serializer.Deserialize(ShortOutput); + [Benchmark] public Int32 _PrimitiveIntDeserialize() => Serializer.Deserialize(IntOutput); + [Benchmark] public Int64 _PrimitiveLongDeserialize() => Serializer.Deserialize(LongOutput); + [Benchmark] public Byte _PrimitiveByteDeserialize() => Serializer.Deserialize(ByteOutput); + [Benchmark] public ushort _PrimitiveUShortDeserialize() => Serializer.Deserialize(UShortOutput); + [Benchmark] public uint _PrimitiveUIntDeserialize() => Serializer.Deserialize(UIntOutput); + [Benchmark] public ulong _PrimitiveULongDeserialize() => Serializer.Deserialize(ULongOutput); + [Benchmark] public bool _PrimitiveBoolDeserialize() => Serializer.Deserialize(BoolOutput); + [Benchmark] public String _PrimitiveStringDeserialize() => Serializer.Deserialize(StringOutput); + [Benchmark] public Char _PrimitiveCharDeserialize() => Serializer.Deserialize(CharOutput); + [Benchmark] public DateTime _PrimitiveDateTimeDeserialize() => Serializer.Deserialize(DateTimeOutput); + [Benchmark] public Guid _PrimitiveGuidDeserialize() => Serializer.Deserialize(GuidOutput); + [Benchmark] public byte[] _PrimitiveBytesDeserialize() => Serializer.Deserialize(BytesOutput); + [Benchmark] public AccessToken AccessTokenDeserialize() => Serializer.Deserialize(AccessTokenOutput); + [Benchmark] public AccountMerge AccountMergeDeserialize() => Serializer.Deserialize(AccountMergeOutput); + [Benchmark] public Answer AnswerDeserialize() => Serializer.Deserialize(AnswerOutput); + [Benchmark] public Badge BadgeDeserialize() => Serializer.Deserialize(BadgeOutput); + [Benchmark] public Comment CommentDeserialize() => Serializer.Deserialize(CommentOutput); + [Benchmark] public Error ErrorDeserialize() => Serializer.Deserialize(ErrorOutput); + [Benchmark] public Event EventDeserialize() => Serializer.Deserialize(EventOutput); + [Benchmark] public MobileFeed MobileFeedDeserialize() => Serializer.Deserialize(MobileFeedOutput); + [Benchmark] public MobileQuestion MobileQuestionDeserialize() => Serializer.Deserialize(MobileQuestionOutput); + [Benchmark] public MobileRepChange MobileRepChangeDeserialize() => Serializer.Deserialize(MobileRepChangeOutput); + [Benchmark] public MobileInboxItem MobileInboxItemDeserialize() => Serializer.Deserialize(MobileInboxItemOutput); + [Benchmark] public MobileBadgeAward MobileBadgeAwardDeserialize() => Serializer.Deserialize(MobileBadgeAwardOutput); + [Benchmark] public MobilePrivilege MobilePrivilegeDeserialize() => Serializer.Deserialize(MobilePrivilegeOutput); + [Benchmark] public MobileCommunityBulletin MobileCommunityBulletinDeserialize() => Serializer.Deserialize(MobileCommunityBulletinOutput); + [Benchmark] public MobileAssociationBonus MobileAssociationBonusDeserialize() => Serializer.Deserialize(MobileAssociationBonusOutput); + [Benchmark] public MobileCareersJobAd MobileCareersJobAdDeserialize() => Serializer.Deserialize(MobileCareersJobAdOutput); + [Benchmark] public MobileBannerAd MobileBannerAdDeserialize() => Serializer.Deserialize(MobileBannerAdOutput); + [Benchmark] public MobileUpdateNotice MobileUpdateNoticeDeserialize() => Serializer.Deserialize(MobileUpdateNoticeOutput); + [Benchmark] public FlagOption FlagOptionDeserialize() => Serializer.Deserialize(FlagOptionOutput); + [Benchmark] public InboxItem InboxItemDeserialize() => Serializer.Deserialize(InboxItemOutput); + [Benchmark] public Info InfoDeserialize() => Serializer.Deserialize(InfoOutput); + [Benchmark] public NetworkUser NetworkUserDeserialize() => Serializer.Deserialize(NetworkUserOutput); + [Benchmark] public Notification NotificationDeserialize() => Serializer.Deserialize(NotificationOutput); + [Benchmark] public Post PostDeserialize() => Serializer.Deserialize(PostOutput); + [Benchmark] public Privilege PrivilegeDeserialize() => Serializer.Deserialize(PrivilegeOutput); + [Benchmark] public Question QuestionDeserialize() => Serializer.Deserialize(QuestionOutput); + [Benchmark] public QuestionTimeline QuestionTimelineDeserialize() => Serializer.Deserialize(QuestionTimelineOutput); + [Benchmark] public Reputation ReputationDeserialize() => Serializer.Deserialize(ReputationOutput); + [Benchmark] public ReputationHistory ReputationHistoryDeserialize() => Serializer.Deserialize(ReputationHistoryOutput); + [Benchmark] public Revision RevisionDeserialize() => Serializer.Deserialize(RevisionOutput); + [Benchmark] public SearchExcerpt SearchExcerptDeserialize() => Serializer.Deserialize(SearchExcerptOutput); + [Benchmark] public ShallowUser ShallowUserDeserialize() => Serializer.Deserialize(ShallowUserOutput); + [Benchmark] public SuggestedEdit SuggestedEditDeserialize() => Serializer.Deserialize(SuggestedEditOutput); + [Benchmark] public Tag TagDeserialize() => Serializer.Deserialize(TagOutput); + [Benchmark] public TagScore TagScoreDeserialize() => Serializer.Deserialize(TagScoreOutput); + [Benchmark] public TagSynonym TagSynonymDeserialize() => Serializer.Deserialize(TagSynonymOutput); + [Benchmark] public TagWiki TagWikiDeserialize() => Serializer.Deserialize(TagWikiOutput); + [Benchmark] public TopTag TopTagDeserialize() => Serializer.Deserialize(TopTagOutput); + [Benchmark] public User UserDeserialize() => Serializer.Deserialize(UserOutput); + [Benchmark] public UserTimeline UserTimelineDeserialize() => Serializer.Deserialize(UserTimelineOutput); + [Benchmark] public WritePermission WritePermissionDeserialize() => Serializer.Deserialize(WritePermissionOutput); + [Benchmark] public MobileBannerAd.MobileBannerAdImage MobileBannerAdImageDeserialize() => Serializer.Deserialize(MobileBannerAdImageOutput); + [Benchmark] public Info.Site SiteDeserialize() => Serializer.Deserialize(SiteOutput); + [Benchmark] public Info.RelatedSite RelatedSiteDeserialize() => Serializer.Deserialize(RelatedSiteOutput); + [Benchmark] public Question.ClosedDetails ClosedDetailsDeserialize() => Serializer.Deserialize(ClosedDetailsOutput); + [Benchmark] public Question.Notice NoticeDeserialize() => Serializer.Deserialize(NoticeOutput); + [Benchmark] public Question.MigrationInfo MigrationInfoDeserialize() => Serializer.Deserialize(MigrationInfoOutput); + [Benchmark] public User.BadgeCount BadgeCountDeserialize() => Serializer.Deserialize(BadgeCountOutput); + [Benchmark] public Info.Site.Styling StylingDeserialize() => Serializer.Deserialize(StylingOutput); + [Benchmark] public Question.ClosedDetails.OriginalQuestion OriginalQuestionDeserialize() => Serializer.Deserialize(OriginalQuestionOutput); + } + + + [Config(typeof(BenchmarkConfig))] + public class MsgPackV1_Vs_MsgPackV2_BytesInOut // : AllSerializerBenchmark + { + [ParamsSource(nameof(Serializers))] + public SerializerBase Serializer; + + // Currently BenchmarkdDotNet does not detect inherited ParamsSource so use copy and paste:) + + public IEnumerable Serializers => new SerializerBase[] + { + new MsgPack_v1(), + new MsgPack_v2(), + }; + + protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); + + // primitives + + protected static readonly sbyte SByteInput = ExpressionTreeFixture.Create(); + protected static readonly short ShortInput = ExpressionTreeFixture.Create(); + protected static readonly int IntInput = ExpressionTreeFixture.Create(); + protected static readonly long LongInput = ExpressionTreeFixture.Create(); + protected static readonly byte ByteInput = ExpressionTreeFixture.Create(); + protected static readonly ushort UShortInput = ExpressionTreeFixture.Create(); + protected static readonly uint UIntInput = ExpressionTreeFixture.Create(); + protected static readonly ulong ULongInput = ExpressionTreeFixture.Create(); + protected static readonly bool BoolInput = ExpressionTreeFixture.Create(); + protected static readonly string StringInput = ExpressionTreeFixture.Create(); + protected static readonly char CharInput = ExpressionTreeFixture.Create(); + protected static readonly DateTime DateTimeInput = ExpressionTreeFixture.Create(); + protected static readonly Guid GuidInput = ExpressionTreeFixture.Create(); + protected static readonly byte[] BytesInput = ExpressionTreeFixture.Create(); + + // models + + protected static readonly Benchmark.Models.AccessToken AccessTokenInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.AccountMerge AccountMergeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Answer AnswerInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Badge BadgeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Comment CommentInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Error ErrorInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Event EventInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileFeed MobileFeedInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileQuestion MobileQuestionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileRepChange MobileRepChangeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileInboxItem MobileInboxItemInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBadgeAward MobileBadgeAwardInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobilePrivilege MobilePrivilegeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileCommunityBulletin MobileCommunityBulletinInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileAssociationBonus MobileAssociationBonusInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileCareersJobAd MobileCareersJobAdInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBannerAd MobileBannerAdInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileUpdateNotice MobileUpdateNoticeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.FlagOption FlagOptionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.InboxItem InboxItemInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info InfoInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.NetworkUser NetworkUserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Notification NotificationInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Post PostInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Privilege PrivilegeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question QuestionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.QuestionTimeline QuestionTimelineInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Reputation ReputationInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.ReputationHistory ReputationHistoryInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Revision RevisionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.SearchExcerpt SearchExcerptInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.ShallowUser ShallowUserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.SuggestedEdit SuggestedEditInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Tag TagInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagScore TagScoreInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagSynonym TagSynonymInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TagWiki TagWikiInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.TopTag TopTagInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.User UserInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.UserTimeline UserTimelineInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.WritePermission WritePermissionInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.MobileBannerAd.MobileBannerAdImage MobileBannerAdImageInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.Site SiteInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.RelatedSite RelatedSiteInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.ClosedDetails ClosedDetailsInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.Notice NoticeInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.MigrationInfo MigrationInfoInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.User.BadgeCount BadgeCountInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Info.Site.Styling StylingInput = ExpressionTreeFixture.Create(); + + protected static readonly Benchmark.Models.Question.ClosedDetails.OriginalQuestion OriginalQuestionInput = ExpressionTreeFixture.Create(); + + object SByteOutput; + object ShortOutput; + object IntOutput; + object LongOutput; + object ByteOutput; + object UShortOutput; + object UIntOutput; + object ULongOutput; + object BoolOutput; + object StringOutput; + object CharOutput; + object DateTimeOutput; + object GuidOutput; + object BytesOutput; + + object AccessTokenOutput; + object AccountMergeOutput; + object AnswerOutput; + object BadgeOutput; + object CommentOutput; + object ErrorOutput; + object EventOutput; + object MobileFeedOutput; + object MobileQuestionOutput; + object MobileRepChangeOutput; + object MobileInboxItemOutput; + object MobileBadgeAwardOutput; + object MobilePrivilegeOutput; + object MobileCommunityBulletinOutput; + object MobileAssociationBonusOutput; + object MobileCareersJobAdOutput; + object MobileBannerAdOutput; + object MobileUpdateNoticeOutput; + object FlagOptionOutput; + object InboxItemOutput; + object InfoOutput; + object NetworkUserOutput; + object NotificationOutput; + object PostOutput; + object PrivilegeOutput; + object QuestionOutput; + object QuestionTimelineOutput; + object ReputationOutput; + object ReputationHistoryOutput; + object RevisionOutput; + object SearchExcerptOutput; + object ShallowUserOutput; + object SuggestedEditOutput; + object TagOutput; + object TagScoreOutput; + object TagSynonymOutput; + object TagWikiOutput; + object TopTagOutput; + object UserOutput; + object UserTimelineOutput; + object WritePermissionOutput; + object MobileBannerAdImageOutput; + object SiteOutput; + object RelatedSiteOutput; + object ClosedDetailsOutput; + object NoticeOutput; + object MigrationInfoOutput; + object BadgeCountOutput; + object StylingOutput; + object OriginalQuestionOutput; + + [GlobalSetup] + public void Setup() + { + // primitives + SByteOutput = Serializer.Serialize(SByteInput); + ShortOutput = Serializer.Serialize(ShortInput); + IntOutput = Serializer.Serialize(IntInput); + LongOutput = Serializer.Serialize(LongInput); + ByteOutput = Serializer.Serialize(ByteInput); + UShortOutput = Serializer.Serialize(UShortInput); + UIntOutput = Serializer.Serialize(UIntInput); + ULongOutput = Serializer.Serialize(ULongInput); + BoolOutput = Serializer.Serialize(BoolInput); + StringOutput = Serializer.Serialize(StringInput); + CharOutput = Serializer.Serialize(CharInput); + DateTimeOutput = Serializer.Serialize(DateTimeInput); + GuidOutput = Serializer.Serialize(GuidInput); + BytesOutput = Serializer.Serialize(BytesInput); + + // models + AccessTokenOutput = Serializer.Serialize(AccessTokenInput); + AccountMergeOutput = Serializer.Serialize(AccountMergeInput); + AnswerOutput = Serializer.Serialize(AnswerInput); + BadgeOutput = Serializer.Serialize(BadgeInput); + CommentOutput = Serializer.Serialize(CommentInput); + ErrorOutput = Serializer.Serialize(ErrorInput); + EventOutput = Serializer.Serialize(EventInput); + MobileFeedOutput = Serializer.Serialize(MobileFeedInput); + MobileQuestionOutput = Serializer.Serialize(MobileQuestionInput); + MobileRepChangeOutput = Serializer.Serialize(MobileRepChangeInput); + MobileInboxItemOutput = Serializer.Serialize(MobileInboxItemInput); + MobileBadgeAwardOutput = Serializer.Serialize(MobileBadgeAwardInput); + MobilePrivilegeOutput = Serializer.Serialize(MobilePrivilegeInput); + MobileCommunityBulletinOutput = Serializer.Serialize(MobileCommunityBulletinInput); + MobileAssociationBonusOutput = Serializer.Serialize(MobileAssociationBonusInput); + MobileCareersJobAdOutput = Serializer.Serialize(MobileCareersJobAdInput); + MobileBannerAdOutput = Serializer.Serialize(MobileBannerAdInput); + MobileUpdateNoticeOutput = Serializer.Serialize(MobileUpdateNoticeInput); + FlagOptionOutput = Serializer.Serialize(FlagOptionInput); + InboxItemOutput = Serializer.Serialize(InboxItemInput); + InfoOutput = Serializer.Serialize(InfoInput); + NetworkUserOutput = Serializer.Serialize(NetworkUserInput); + NotificationOutput = Serializer.Serialize(NotificationInput); + PostOutput = Serializer.Serialize(PostInput); + PrivilegeOutput = Serializer.Serialize(PrivilegeInput); + QuestionOutput = Serializer.Serialize(QuestionInput); + QuestionTimelineOutput = Serializer.Serialize(QuestionTimelineInput); + ReputationOutput = Serializer.Serialize(ReputationInput); + ReputationHistoryOutput = Serializer.Serialize(ReputationHistoryInput); + RevisionOutput = Serializer.Serialize(RevisionInput); + SearchExcerptOutput = Serializer.Serialize(SearchExcerptInput); + ShallowUserOutput = Serializer.Serialize(ShallowUserInput); + SuggestedEditOutput = Serializer.Serialize(SuggestedEditInput); + TagOutput = Serializer.Serialize(TagInput); + TagScoreOutput = Serializer.Serialize(TagScoreInput); + TagSynonymOutput = Serializer.Serialize(TagSynonymInput); + TagWikiOutput = Serializer.Serialize(TagWikiInput); + TopTagOutput = Serializer.Serialize(TopTagInput); + UserOutput = Serializer.Serialize(UserInput); + UserTimelineOutput = Serializer.Serialize(UserTimelineInput); + WritePermissionOutput = Serializer.Serialize(WritePermissionInput); + MobileBannerAdImageOutput = Serializer.Serialize(MobileBannerAdImageInput); + SiteOutput = Serializer.Serialize(SiteInput); + RelatedSiteOutput = Serializer.Serialize(RelatedSiteInput); + ClosedDetailsOutput = Serializer.Serialize(ClosedDetailsInput); + NoticeOutput = Serializer.Serialize(NoticeInput); + MigrationInfoOutput = Serializer.Serialize(MigrationInfoInput); + BadgeCountOutput = Serializer.Serialize(BadgeCountInput); + StylingOutput = Serializer.Serialize(StylingInput); + OriginalQuestionOutput = Serializer.Serialize(OriginalQuestionInput); + } + + // Serialize + + [Benchmark] public object _PrimitiveSByteSerialize() => Serializer.Serialize(SByteInput); + [Benchmark] public object _PrimitiveShortSerialize() => Serializer.Serialize(ShortInput); + [Benchmark] public object _PrimitiveIntSerialize() => Serializer.Serialize(IntInput); + [Benchmark] public object _PrimitiveLongSerialize() => Serializer.Serialize(LongInput); + [Benchmark] public object _PrimitiveByteSerialize() => Serializer.Serialize(ByteInput); + [Benchmark] public object _PrimitiveUShortSerialize() => Serializer.Serialize(UShortInput); + [Benchmark] public object _PrimitiveUIntSerialize() => Serializer.Serialize(UIntInput); + [Benchmark] public object _PrimitiveULongSerialize() => Serializer.Serialize(ULongInput); + [Benchmark] public object _PrimitiveBoolSerialize() => Serializer.Serialize(BoolInput); + [Benchmark] public object _PrimitiveStringSerialize() => Serializer.Serialize(StringInput); + [Benchmark] public object _PrimitiveCharSerialize() => Serializer.Serialize(CharInput); + [Benchmark] public object _PrimitiveDateTimeSerialize() => Serializer.Serialize(DateTimeInput); + [Benchmark] public object _PrimitiveGuidSerialize() => Serializer.Serialize(GuidInput); + [Benchmark] public object _PrimitiveBytesSerialize() => Serializer.Serialize(BytesInput); + + [Benchmark] public object AccessTokenSerialize() => Serializer.Serialize(AccessTokenInput); + [Benchmark] public object AccountMergeSerialize() => Serializer.Serialize(AccountMergeInput); + [Benchmark] public object AnswerSerialize() => Serializer.Serialize(AnswerInput); + [Benchmark] public object BadgeSerialize() => Serializer.Serialize(BadgeInput); + [Benchmark] public object CommentSerialize() => Serializer.Serialize(CommentInput); + [Benchmark] public object ErrorSerialize() => Serializer.Serialize(ErrorInput); + [Benchmark] public object EventSerialize() => Serializer.Serialize(EventInput); + [Benchmark] public object MobileFeedSerialize() => Serializer.Serialize(MobileFeedInput); + [Benchmark] public object MobileQuestionSerialize() => Serializer.Serialize(MobileQuestionInput); + [Benchmark] public object MobileRepChangeSerialize() => Serializer.Serialize(MobileRepChangeInput); + [Benchmark] public object MobileInboxItemSerialize() => Serializer.Serialize(MobileInboxItemInput); + [Benchmark] public object MobileBadgeAwardSerialize() => Serializer.Serialize(MobileBadgeAwardInput); + [Benchmark] public object MobilePrivilegeSerialize() => Serializer.Serialize(MobilePrivilegeInput); + [Benchmark] public object MobileCommunityBulletinSerialize() => Serializer.Serialize(MobileCommunityBulletinInput); + [Benchmark] public object MobileAssociationBonusSerialize() => Serializer.Serialize(MobileAssociationBonusInput); + [Benchmark] public object MobileCareersJobAdSerialize() => Serializer.Serialize(MobileCareersJobAdInput); + [Benchmark] public object MobileBannerAdSerialize() => Serializer.Serialize(MobileBannerAdInput); + [Benchmark] public object MobileUpdateNoticeSerialize() => Serializer.Serialize(MobileUpdateNoticeInput); + [Benchmark] public object FlagOptionSerialize() => Serializer.Serialize(FlagOptionInput); + [Benchmark] public object InboxItemSerialize() => Serializer.Serialize(InboxItemInput); + [Benchmark] public object InfoSerialize() => Serializer.Serialize(InfoInput); + [Benchmark] public object NetworkUserSerialize() => Serializer.Serialize(NetworkUserInput); + [Benchmark] public object NotificationSerialize() => Serializer.Serialize(NotificationInput); + [Benchmark] public object PostSerialize() => Serializer.Serialize(PostInput); + [Benchmark] public object PrivilegeSerialize() => Serializer.Serialize(PrivilegeInput); + [Benchmark] public object QuestionSerialize() => Serializer.Serialize(QuestionInput); + [Benchmark] public object QuestionTimelineSerialize() => Serializer.Serialize(QuestionTimelineInput); + [Benchmark] public object ReputationSerialize() => Serializer.Serialize(ReputationInput); + [Benchmark] public object ReputationHistorySerialize() => Serializer.Serialize(ReputationHistoryInput); + [Benchmark] public object RevisionSerialize() => Serializer.Serialize(RevisionInput); + [Benchmark] public object SearchExcerptSerialize() => Serializer.Serialize(SearchExcerptInput); + [Benchmark] public object ShallowUserSerialize() => Serializer.Serialize(ShallowUserInput); + [Benchmark] public object SuggestedEditSerialize() => Serializer.Serialize(SuggestedEditInput); + [Benchmark] public object TagSerialize() => Serializer.Serialize(TagInput); + [Benchmark] public object TagScoreSerialize() => Serializer.Serialize(TagScoreInput); + [Benchmark] public object TagSynonymSerialize() => Serializer.Serialize(TagSynonymInput); + [Benchmark] public object TagWikiSerialize() => Serializer.Serialize(TagWikiInput); + [Benchmark] public object TopTagSerialize() => Serializer.Serialize(TopTagInput); + [Benchmark] public object UserSerialize() => Serializer.Serialize(UserInput); + [Benchmark] public object UserTimelineSerialize() => Serializer.Serialize(UserTimelineInput); + [Benchmark] public object WritePermissionSerialize() => Serializer.Serialize(WritePermissionInput); + [Benchmark] public object MobileBannerAdImageSerialize() => Serializer.Serialize(MobileBannerAdImageInput); + [Benchmark] public object SiteSerialize() => Serializer.Serialize(SiteInput); + [Benchmark] public object RelatedSiteSerialize() => Serializer.Serialize(RelatedSiteInput); + [Benchmark] public object ClosedDetailsSerialize() => Serializer.Serialize(ClosedDetailsInput); + [Benchmark] public object NoticeSerialize() => Serializer.Serialize(NoticeInput); + [Benchmark] public object MigrationInfoSerialize() => Serializer.Serialize(MigrationInfoInput); + [Benchmark] public object BadgeCountSerialize() => Serializer.Serialize(BadgeCountInput); + [Benchmark] public object StylingSerialize() => Serializer.Serialize(StylingInput); + [Benchmark] public object OriginalQuestionSerialize() => Serializer.Serialize(OriginalQuestionInput); + + // Deserialize + + [Benchmark] public SByte _PrimitiveSByteDeserialize() => Serializer.Deserialize(SByteOutput); + [Benchmark] public short _PrimitiveShortDeserialize() => Serializer.Deserialize(ShortOutput); + [Benchmark] public Int32 _PrimitiveIntDeserialize() => Serializer.Deserialize(IntOutput); + [Benchmark] public Int64 _PrimitiveLongDeserialize() => Serializer.Deserialize(LongOutput); + [Benchmark] public Byte _PrimitiveByteDeserialize() => Serializer.Deserialize(ByteOutput); + [Benchmark] public ushort _PrimitiveUShortDeserialize() => Serializer.Deserialize(UShortOutput); + [Benchmark] public uint _PrimitiveUIntDeserialize() => Serializer.Deserialize(UIntOutput); + [Benchmark] public ulong _PrimitiveULongDeserialize() => Serializer.Deserialize(ULongOutput); + [Benchmark] public bool _PrimitiveBoolDeserialize() => Serializer.Deserialize(BoolOutput); + [Benchmark] public String _PrimitiveStringDeserialize() => Serializer.Deserialize(StringOutput); + [Benchmark] public Char _PrimitiveCharDeserialize() => Serializer.Deserialize(CharOutput); + [Benchmark] public DateTime _PrimitiveDateTimeDeserialize() => Serializer.Deserialize(DateTimeOutput); + [Benchmark] public Guid _PrimitiveGuidDeserialize() => Serializer.Deserialize(GuidOutput); + [Benchmark] public byte[] _PrimitiveBytesDeserialize() => Serializer.Deserialize(BytesOutput); + [Benchmark] public AccessToken AccessTokenDeserialize() => Serializer.Deserialize(AccessTokenOutput); + [Benchmark] public AccountMerge AccountMergeDeserialize() => Serializer.Deserialize(AccountMergeOutput); + [Benchmark] public Answer AnswerDeserialize() => Serializer.Deserialize(AnswerOutput); + [Benchmark] public Badge BadgeDeserialize() => Serializer.Deserialize(BadgeOutput); + [Benchmark] public Comment CommentDeserialize() => Serializer.Deserialize(CommentOutput); + [Benchmark] public Error ErrorDeserialize() => Serializer.Deserialize(ErrorOutput); + [Benchmark] public Event EventDeserialize() => Serializer.Deserialize(EventOutput); + [Benchmark] public MobileFeed MobileFeedDeserialize() => Serializer.Deserialize(MobileFeedOutput); + [Benchmark] public MobileQuestion MobileQuestionDeserialize() => Serializer.Deserialize(MobileQuestionOutput); + [Benchmark] public MobileRepChange MobileRepChangeDeserialize() => Serializer.Deserialize(MobileRepChangeOutput); + [Benchmark] public MobileInboxItem MobileInboxItemDeserialize() => Serializer.Deserialize(MobileInboxItemOutput); + [Benchmark] public MobileBadgeAward MobileBadgeAwardDeserialize() => Serializer.Deserialize(MobileBadgeAwardOutput); + [Benchmark] public MobilePrivilege MobilePrivilegeDeserialize() => Serializer.Deserialize(MobilePrivilegeOutput); + [Benchmark] public MobileCommunityBulletin MobileCommunityBulletinDeserialize() => Serializer.Deserialize(MobileCommunityBulletinOutput); + [Benchmark] public MobileAssociationBonus MobileAssociationBonusDeserialize() => Serializer.Deserialize(MobileAssociationBonusOutput); + [Benchmark] public MobileCareersJobAd MobileCareersJobAdDeserialize() => Serializer.Deserialize(MobileCareersJobAdOutput); + [Benchmark] public MobileBannerAd MobileBannerAdDeserialize() => Serializer.Deserialize(MobileBannerAdOutput); + [Benchmark] public MobileUpdateNotice MobileUpdateNoticeDeserialize() => Serializer.Deserialize(MobileUpdateNoticeOutput); + [Benchmark] public FlagOption FlagOptionDeserialize() => Serializer.Deserialize(FlagOptionOutput); + [Benchmark] public InboxItem InboxItemDeserialize() => Serializer.Deserialize(InboxItemOutput); + [Benchmark] public Info InfoDeserialize() => Serializer.Deserialize(InfoOutput); + [Benchmark] public NetworkUser NetworkUserDeserialize() => Serializer.Deserialize(NetworkUserOutput); + [Benchmark] public Notification NotificationDeserialize() => Serializer.Deserialize(NotificationOutput); + [Benchmark] public Post PostDeserialize() => Serializer.Deserialize(PostOutput); + [Benchmark] public Privilege PrivilegeDeserialize() => Serializer.Deserialize(PrivilegeOutput); + [Benchmark] public Question QuestionDeserialize() => Serializer.Deserialize(QuestionOutput); + [Benchmark] public QuestionTimeline QuestionTimelineDeserialize() => Serializer.Deserialize(QuestionTimelineOutput); + [Benchmark] public Reputation ReputationDeserialize() => Serializer.Deserialize(ReputationOutput); + [Benchmark] public ReputationHistory ReputationHistoryDeserialize() => Serializer.Deserialize(ReputationHistoryOutput); + [Benchmark] public Revision RevisionDeserialize() => Serializer.Deserialize(RevisionOutput); + [Benchmark] public SearchExcerpt SearchExcerptDeserialize() => Serializer.Deserialize(SearchExcerptOutput); + [Benchmark] public ShallowUser ShallowUserDeserialize() => Serializer.Deserialize(ShallowUserOutput); + [Benchmark] public SuggestedEdit SuggestedEditDeserialize() => Serializer.Deserialize(SuggestedEditOutput); + [Benchmark] public Tag TagDeserialize() => Serializer.Deserialize(TagOutput); + [Benchmark] public TagScore TagScoreDeserialize() => Serializer.Deserialize(TagScoreOutput); + [Benchmark] public TagSynonym TagSynonymDeserialize() => Serializer.Deserialize(TagSynonymOutput); + [Benchmark] public TagWiki TagWikiDeserialize() => Serializer.Deserialize(TagWikiOutput); + [Benchmark] public TopTag TopTagDeserialize() => Serializer.Deserialize(TopTagOutput); + [Benchmark] public User UserDeserialize() => Serializer.Deserialize(UserOutput); + [Benchmark] public UserTimeline UserTimelineDeserialize() => Serializer.Deserialize(UserTimelineOutput); + [Benchmark] public WritePermission WritePermissionDeserialize() => Serializer.Deserialize(WritePermissionOutput); + [Benchmark] public MobileBannerAd.MobileBannerAdImage MobileBannerAdImageDeserialize() => Serializer.Deserialize(MobileBannerAdImageOutput); + [Benchmark] public Info.Site SiteDeserialize() => Serializer.Deserialize(SiteOutput); + [Benchmark] public Info.RelatedSite RelatedSiteDeserialize() => Serializer.Deserialize(RelatedSiteOutput); + [Benchmark] public Question.ClosedDetails ClosedDetailsDeserialize() => Serializer.Deserialize(ClosedDetailsOutput); + [Benchmark] public Question.Notice NoticeDeserialize() => Serializer.Deserialize(NoticeOutput); + [Benchmark] public Question.MigrationInfo MigrationInfoDeserialize() => Serializer.Deserialize(MigrationInfoOutput); + [Benchmark] public User.BadgeCount BadgeCountDeserialize() => Serializer.Deserialize(BadgeCountOutput); + [Benchmark] public Info.Site.Styling StylingDeserialize() => Serializer.Deserialize(StylingOutput); + [Benchmark] public Question.ClosedDetails.OriginalQuestion OriginalQuestionDeserialize() => Serializer.Deserialize(OriginalQuestionOutput); + } + + + [Config(typeof(BenchmarkConfig))] + public class ShortRun_AllSerializerBenchmark_BytesInOut + { + [ParamsSource(nameof(Serializers))] + public SerializerBase Serializer; + + // Currently BenchmarkdDotNet does not detect inherited ParamsSource so use copy and paste:) + + public IEnumerable Serializers => new SerializerBase[] + { + new MsgPack_v1(), + new MsgPack_v2(), + new MsgPackLz4_v1(), + new MsgPackLz4_v2(), + new Protobuf(), + new JsonNet(), + new BinaryFormatter_(), + new DataContract_(), + new Hyperion_(), + new Jil_(), + new SpanJson_(), + new Utf8Json_(), + new MsgPackCli(), + new FsPickler_() + }; + + protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); + + // primitives + + protected static readonly int IntInput = ExpressionTreeFixture.Create(); + + // models + + protected static readonly Benchmark.Models.Answer AnswerInput = ExpressionTreeFixture.Create(); + + object IntOutput; + object AnswerOutput; + + + [GlobalSetup] + public void Setup() + { + // primitives + IntOutput = Serializer.Serialize(IntInput); + + // models + AnswerOutput = Serializer.Serialize(AnswerInput); + } + + // Serialize + + [Benchmark] public object _PrimitiveIntSerialize() => Serializer.Serialize(IntInput); + [Benchmark] public object AnswerSerialize() => Serializer.Serialize(AnswerInput); + + // Deserialize + + [Benchmark] public Int32 _PrimitiveIntDeserialize() => Serializer.Deserialize(IntOutput); + + [Benchmark] public Answer AnswerDeserialize() => Serializer.Deserialize(AnswerOutput); + } + + [Config(typeof(BenchmarkConfig))] + public class ShortRun_MsgPackV1_Vs_MsgPackV2_BytesInOut + { + [ParamsSource(nameof(Serializers))] + public SerializerBase Serializer; + + // Currently BenchmarkdDotNet does not detect inherited ParamsSource so use copy and paste:) + + public IEnumerable Serializers => new SerializerBase[] + { + new MsgPack_v1(), + new MsgPack_v2(), + }; + + protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); + + // primitives + + protected static readonly int IntInput = ExpressionTreeFixture.Create(); + + // models + + protected static readonly Benchmark.Models.Answer AnswerInput = ExpressionTreeFixture.Create(); + + object IntOutput; + object AnswerOutput; + + + [GlobalSetup] + public void Setup() + { + // primitives + IntOutput = Serializer.Serialize(IntInput); + + // models + AnswerOutput = Serializer.Serialize(AnswerInput); + } + + // Serialize + + [Benchmark] public object _PrimitiveIntSerialize() => Serializer.Serialize(IntInput); + [Benchmark] public object AnswerSerialize() => Serializer.Serialize(AnswerInput); + + // Deserialize + + [Benchmark] public Int32 _PrimitiveIntDeserialize() => Serializer.Deserialize(IntOutput); + + [Benchmark] public Answer AnswerDeserialize() => Serializer.Deserialize(AnswerOutput); + } +} diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.csproj b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj new file mode 100644 index 00000000..14700daf --- /dev/null +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj @@ -0,0 +1,45 @@ + + + + Exe + netcoreapp2.1 + SerializerBenchmark + Benchmark + + + + true + + + + true + + + + + + + + + + + + + + + + + newmsgpack + + + + + + MessagePack_1_7_3_6.dll + oldmsgpack + true + false + + + + diff --git a/benchmark/SerializerBenchmark/Serializers/BinaryFormatter.cs b/benchmark/SerializerBenchmark/Serializers/BinaryFormatter.cs new file mode 100644 index 00000000..85065df9 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/BinaryFormatter.cs @@ -0,0 +1,24 @@ +using Benchmark.Serializers; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; + +public class BinaryFormatter_ : SerializerBase +{ + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + { + return (T)new BinaryFormatter().Deserialize(ms); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + new BinaryFormatter().Serialize(ms, input); + ms.Flush(); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/DataContractSerializer.cs b/benchmark/SerializerBenchmark/Serializers/DataContractSerializer.cs new file mode 100644 index 00000000..8ba0a1c2 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/DataContractSerializer.cs @@ -0,0 +1,24 @@ +using Benchmark.Serializers; +using System.IO; +using System.Runtime.Serialization; + +public class DataContract_ : SerializerBase +{ + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + { + return (T)new DataContractSerializer(typeof(T)).ReadObject(ms); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + new DataContractSerializer(typeof(T)).WriteObject(ms, input); + ms.Flush(); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/FsPicklerSerializer.cs b/benchmark/SerializerBenchmark/Serializers/FsPicklerSerializer.cs new file mode 100644 index 00000000..778b3113 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/FsPicklerSerializer.cs @@ -0,0 +1,26 @@ +using Benchmark.Serializers; +using MBrace.FsPickler; +using System.IO; + +public class FsPickler_ : SerializerBase +{ + static readonly BinarySerializer serializer = MBrace.FsPickler.FsPickler.CreateBinarySerializer(); + + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + { + return serializer.Deserialize(ms); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + serializer.Serialize(ms, input); + ms.Flush(); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/HyperionSerializer.cs b/benchmark/SerializerBenchmark/Serializers/HyperionSerializer.cs new file mode 100644 index 00000000..517fbe3c --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/HyperionSerializer.cs @@ -0,0 +1,26 @@ +using Benchmark.Serializers; +using Hyperion; +using System.IO; + +public class Hyperion_ : SerializerBase +{ + static readonly Serializer serializer = new Hyperion.Serializer(); + + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + { + return serializer.Deserialize(ms); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + serializer.Serialize(input, ms); + ms.Flush(); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/JilSerializer.cs b/benchmark/SerializerBenchmark/Serializers/JilSerializer.cs new file mode 100644 index 00000000..e0d14936 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/JilSerializer.cs @@ -0,0 +1,16 @@ +using Benchmark.Serializers; +using Jil; +using System.Text; + +public class Jil_ : SerializerBase +{ + public override object Serialize(T input) + { + return Encoding.UTF8.GetBytes(Jil.JSON.Serialize(input, Options.ISO8601)); + } + + public override T Deserialize(object input) + { + return Jil.JSON.Deserialize(Encoding.UTF8.GetString((byte[])input), Options.ISO8601); + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Serializers/JsonNetSerializer.cs b/benchmark/SerializerBenchmark/Serializers/JsonNetSerializer.cs new file mode 100644 index 00000000..bddffb30 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/JsonNetSerializer.cs @@ -0,0 +1,33 @@ +using Benchmark.Serializers; +using Newtonsoft.Json; +using System.IO; +using System.Text; + +public class JsonNet : SerializerBase +{ + static readonly JsonSerializer serializer = new JsonSerializer(); + + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + using (var sr = new StreamReader(ms, Encoding.UTF8)) + using (var jr = new JsonTextReader(sr)) + { + return serializer.Deserialize(jr); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + using (var sw = new StreamWriter(ms, Encoding.UTF8)) + using (var jw = new JsonTextWriter(sw)) + { + serializer.Serialize(jw, input); + } + ms.Flush(); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs new file mode 100644 index 00000000..1f3c343c --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs @@ -0,0 +1,56 @@ +extern alias oldmsgpack; +extern alias newmsgpack; + +using Benchmark.Serializers; + +public class MsgPack_v1 : SerializerBase +{ + public override T Deserialize(object input) + { + return oldmsgpack::MessagePack.MessagePackSerializer.Deserialize((byte[])input); + } + + public override object Serialize(T input) + { + return oldmsgpack::MessagePack.MessagePackSerializer.Serialize(input); + } +} + +public class MsgPack_v2 : SerializerBase +{ + public override T Deserialize(object input) + { + return newmsgpack::MessagePack.MessagePackSerializer.Deserialize((byte[])input); + } + + public override object Serialize(T input) + { + return newmsgpack::MessagePack.MessagePackSerializer.Serialize(input); + } +} + +public class MsgPackLz4_v1 : SerializerBase +{ + public override T Deserialize(object input) + { + return oldmsgpack::MessagePack.LZ4MessagePackSerializer.Deserialize((byte[])input); + } + + public override object Serialize(T input) + { + return oldmsgpack::MessagePack.LZ4MessagePackSerializer.Serialize(input); + } +} + +public class MsgPackLz4_v2 : SerializerBase +{ + public override T Deserialize(object input) + { + return newmsgpack::MessagePack.LZ4MessagePackSerializer.Deserialize((byte[])input); + } + + public override object Serialize(T input) + { + return newmsgpack::MessagePack.LZ4MessagePackSerializer.Serialize(input); + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Serializers/MsgPackCliSerializer.cs b/benchmark/SerializerBenchmark/Serializers/MsgPackCliSerializer.cs new file mode 100644 index 00000000..77f97b9d --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/MsgPackCliSerializer.cs @@ -0,0 +1,14 @@ +using Benchmark.Serializers; + +public class MsgPackCli : SerializerBase +{ + public override T Deserialize(object input) + { + return MsgPack.Serialization.MessagePackSerializer.Get().UnpackSingleObject((byte[])input); + } + + public override object Serialize(T input) + { + return MsgPack.Serialization.MessagePackSerializer.Get().PackSingleObject(input); + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs b/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs new file mode 100644 index 00000000..eab51f63 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs @@ -0,0 +1,23 @@ +using Benchmark.Serializers; +using ProtoBuf; +using System.IO; + +public class Protobuf : SerializerBase +{ + public override T Deserialize(object input) + { + using (var ms = new MemoryStream((byte[])input)) + { + return Serializer.Deserialize(ms); + } + } + + public override object Serialize(T input) + { + using (var ms = new MemoryStream()) + { + Serializer.Serialize(ms, input); + return ms.ToArray(); + } + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/SerializerBase.cs b/benchmark/SerializerBenchmark/Serializers/SerializerBase.cs new file mode 100644 index 00000000..6bcd133c --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/SerializerBase.cs @@ -0,0 +1,13 @@ +using System; + +namespace Benchmark.Serializers +{ + public abstract class SerializerBase + { + public abstract object Serialize(T input); + + public abstract T Deserialize(object input); + + + } +} \ No newline at end of file diff --git a/benchmark/SerializerBenchmark/Serializers/SpanJsonSerializer.cs b/benchmark/SerializerBenchmark/Serializers/SpanJsonSerializer.cs new file mode 100644 index 00000000..6407eb7e --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/SpanJsonSerializer.cs @@ -0,0 +1,14 @@ +using Benchmark.Serializers; + +public class SpanJson_ : SerializerBase +{ + public override object Serialize(T input) + { + return SpanJson.JsonSerializer.Generic.Utf8.Serialize(input); + } + + public override T Deserialize(object input) + { + return SpanJson.JsonSerializer.Generic.Utf8.Deserialize((byte[])input); + } +} diff --git a/benchmark/SerializerBenchmark/Serializers/Utf8JsonSerializer.cs b/benchmark/SerializerBenchmark/Serializers/Utf8JsonSerializer.cs new file mode 100644 index 00000000..70070b12 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/Utf8JsonSerializer.cs @@ -0,0 +1,14 @@ +using Benchmark.Serializers; + +public class Utf8Json_ : SerializerBase +{ + public override object Serialize(T input) + { + return Utf8Json.JsonSerializer.Serialize(input); + } + + public override T Deserialize(object input) + { + return Utf8Json.JsonSerializer.Deserialize((byte[])input); + } +} diff --git a/src/MessagePack/MessagePack.csproj b/src/MessagePack/MessagePack.csproj index 8b32e40f..cd48adf2 100644 --- a/src/MessagePack/MessagePack.csproj +++ b/src/MessagePack/MessagePack.csproj @@ -11,10 +11,17 @@ MessagePack for C# Extremely Fast MessagePack(MsgPack) Serializer for C#(.NET, .NET Core, Unity, Xamarin). MsgPack;MessagePack;Serialization;Formatter;Serializer;Unity;Xamarin + MessagePack + + + + + + From 6fe0a351aff6df2b8a0b77eca7eca9aa5973b048 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Sun, 10 Mar 2019 22:36:32 +0900 Subject: [PATCH 2/5] Benchmark rename, MsgPack -> MessagePack --- .../SerializerBenchmark.cs | 24 +++++++++---------- .../Serializers/MessagePackSerializer.cs | 8 +++---- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.cs b/benchmark/SerializerBenchmark/SerializerBenchmark.cs index 8f1a7f03..f6fa04c9 100644 --- a/benchmark/SerializerBenchmark/SerializerBenchmark.cs +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.cs @@ -17,10 +17,10 @@ public IEnumerable Serializers => new SerializerBase[] { - new MsgPack_v1(), - new MsgPack_v2(), - new MsgPackLz4_v1(), - new MsgPackLz4_v2(), + new MessagePack_v1(), + new MessagePack_v2(), + new MessagePackLz4_v1(), + new MessagePackLz4_v2(), new Protobuf(), new JsonNet(), new BinaryFormatter_(), @@ -439,8 +439,8 @@ public IEnumerable Serializers => new SerializerBase[] { - new MsgPack_v1(), - new MsgPack_v2(), + new MessagePack_v1(), + new MessagePack_v2(), }; protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); @@ -849,10 +849,10 @@ public IEnumerable Serializers => new SerializerBase[] { - new MsgPack_v1(), - new MsgPack_v2(), - new MsgPackLz4_v1(), - new MsgPackLz4_v2(), + new MessagePack_v1(), + new MessagePack_v2(), + new MessagePackLz4_v1(), + new MessagePackLz4_v2(), new Protobuf(), new JsonNet(), new BinaryFormatter_(), @@ -911,8 +911,8 @@ public IEnumerable Serializers => new SerializerBase[] { - new MsgPack_v1(), - new MsgPack_v2(), + new MessagePack_v1(), + new MessagePack_v2(), }; protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); diff --git a/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs index 1f3c343c..ec66b03b 100644 --- a/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs +++ b/benchmark/SerializerBenchmark/Serializers/MessagePackSerializer.cs @@ -3,7 +3,7 @@ extern alias newmsgpack; using Benchmark.Serializers; -public class MsgPack_v1 : SerializerBase +public class MessagePack_v1 : SerializerBase { public override T Deserialize(object input) { @@ -16,7 +16,7 @@ public class MsgPack_v1 : SerializerBase } } -public class MsgPack_v2 : SerializerBase +public class MessagePack_v2 : SerializerBase { public override T Deserialize(object input) { @@ -29,7 +29,7 @@ public class MsgPack_v2 : SerializerBase } } -public class MsgPackLz4_v1 : SerializerBase +public class MessagePackLz4_v1 : SerializerBase { public override T Deserialize(object input) { @@ -42,7 +42,7 @@ public class MsgPackLz4_v1 : SerializerBase } } -public class MsgPackLz4_v2 : SerializerBase +public class MessagePackLz4_v2 : SerializerBase { public override T Deserialize(object input) { From e2d3a67edc7090ba89ceba31264ded4102862e5e Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Sun, 10 Mar 2019 22:46:38 +0900 Subject: [PATCH 3/5] Add CerasSerializer Benchmark --- benchmark/SerializerBenchmark/Program.cs | 1 + .../SerializerBenchmark/SerializerBenchmark.cs | 6 ++++-- .../SerializerBenchmark.csproj | 1 + .../Serializers/CerasSerializer.cs | 16 ++++++++++++++++ 4 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 benchmark/SerializerBenchmark/Serializers/CerasSerializer.cs diff --git a/benchmark/SerializerBenchmark/Program.cs b/benchmark/SerializerBenchmark/Program.cs index 73b95297..4ad5bf65 100644 --- a/benchmark/SerializerBenchmark/Program.cs +++ b/benchmark/SerializerBenchmark/Program.cs @@ -8,6 +8,7 @@ namespace ConsoleApp1 static void Main(string[] args) { BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); + // BenchmarkRunner.Run(); } } } diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.cs b/benchmark/SerializerBenchmark/SerializerBenchmark.cs index f6fa04c9..a22c1d55 100644 --- a/benchmark/SerializerBenchmark/SerializerBenchmark.cs +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.cs @@ -30,7 +30,8 @@ new SpanJson_(), new Utf8Json_(), new MsgPackCli(), - new FsPickler_() + new FsPickler_(), + new Ceras_(), }; protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); @@ -862,7 +863,8 @@ new SpanJson_(), new Utf8Json_(), new MsgPackCli(), - new FsPickler_() + new FsPickler_(), + new Ceras_(), }; protected static readonly ExpressionTreeFixture ExpressionTreeFixture = new ExpressionTreeFixture(); diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.csproj b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj index 14700daf..7f857bfc 100644 --- a/benchmark/SerializerBenchmark/SerializerBenchmark.csproj +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.csproj @@ -17,6 +17,7 @@ + diff --git a/benchmark/SerializerBenchmark/Serializers/CerasSerializer.cs b/benchmark/SerializerBenchmark/Serializers/CerasSerializer.cs new file mode 100644 index 00000000..a8fb7944 --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/CerasSerializer.cs @@ -0,0 +1,16 @@ +using Benchmark.Serializers; + +public class Ceras_ : SerializerBase +{ + Ceras.CerasSerializer ceras = new Ceras.CerasSerializer(); + + public override T Deserialize(object input) + { + return ceras.Deserialize((byte[])input); + } + + public override object Serialize(T input) + { + return ceras.Serialize(input); + } +} From 02312922213630be3b81a3ac5d2096199cf08d66 Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Sun, 10 Mar 2019 22:50:11 +0900 Subject: [PATCH 4/5] Rename Benchmark, Protobuf -> ProtobufNet --- benchmark/SerializerBenchmark/SerializerBenchmark.cs | 4 ++-- .../SerializerBenchmark/Serializers/ProtobufSerializer.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/benchmark/SerializerBenchmark/SerializerBenchmark.cs b/benchmark/SerializerBenchmark/SerializerBenchmark.cs index a22c1d55..b80f8bcb 100644 --- a/benchmark/SerializerBenchmark/SerializerBenchmark.cs +++ b/benchmark/SerializerBenchmark/SerializerBenchmark.cs @@ -21,7 +21,7 @@ new MessagePack_v2(), new MessagePackLz4_v1(), new MessagePackLz4_v2(), - new Protobuf(), + new ProtobufNet(), new JsonNet(), new BinaryFormatter_(), new DataContract_(), @@ -854,7 +854,7 @@ new MessagePack_v2(), new MessagePackLz4_v1(), new MessagePackLz4_v2(), - new Protobuf(), + new ProtobufNet(), new JsonNet(), new BinaryFormatter_(), new DataContract_(), diff --git a/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs b/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs index eab51f63..00381992 100644 --- a/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs +++ b/benchmark/SerializerBenchmark/Serializers/ProtobufSerializer.cs @@ -2,7 +2,7 @@ using ProtoBuf; using System.IO; -public class Protobuf : SerializerBase +public class ProtobufNet : SerializerBase { public override T Deserialize(object input) { From 1ab6f5029b6e3480a4969bf56979f1bc5fb8236f Mon Sep 17 00:00:00 2001 From: Yoshifumi Kawai Date: Mon, 11 Mar 2019 00:13:49 +0900 Subject: [PATCH 5/5] Add DataSize column to Benchmark --- .../SerializerBenchmark/BenchmarkConfig.cs | 90 +++++++++++++++++++ benchmark/SerializerBenchmark/Program.cs | 3 +- .../Serializers/HagarSerializer.cs | 56 ++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 benchmark/SerializerBenchmark/Serializers/HagarSerializer.cs diff --git a/benchmark/SerializerBenchmark/BenchmarkConfig.cs b/benchmark/SerializerBenchmark/BenchmarkConfig.cs index 4e72a985..c88d5d3a 100644 --- a/benchmark/SerializerBenchmark/BenchmarkConfig.cs +++ b/benchmark/SerializerBenchmark/BenchmarkConfig.cs @@ -1,4 +1,5 @@ using Benchmark.Serializers; +using BenchmarkDotNet.Columns; using BenchmarkDotNet.Configs; using BenchmarkDotNet.Diagnosers; using BenchmarkDotNet.Environments; @@ -8,6 +9,7 @@ using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; using BenchmarkDotNet.Reports; using BenchmarkDotNet.Running; +using System; using System.Collections.Generic; using System.Linq; @@ -27,6 +29,8 @@ namespace Benchmark Add(CsvExporter.Default); Add(MemoryDiagnoser.Default); + Add(new DataSizeColumn()); + this.Set(new CustomOrderer()); } @@ -64,5 +68,91 @@ namespace Benchmark .ThenBy(x => x.Parameters.Items.Select(y => y.Value).OfType().First().GetType().Name); } } + + public class DataSizeColumn : IColumn + { + public string Id => "DataSize"; + + public string ColumnName => "DataSize"; + + public bool AlwaysShow => true; + + public ColumnCategory Category => ColumnCategory.Custom; + + public int PriorityInCategory => int.MaxValue; + + public bool IsNumeric => true; + + public UnitType UnitType => UnitType.Size; + + public string Legend => null; + + public string GetValue(Summary summary, BenchmarkCase benchmarkCase) + { + return GetValue(summary, benchmarkCase, null); + } + + public string GetValue(Summary summary, BenchmarkCase benchmarkCase, ISummaryStyle style) + { + var mi = benchmarkCase.Descriptor.WorkloadMethod; + if (mi.Name.Contains("Serialize")) + { + var instance = Activator.CreateInstance(mi.DeclaringType); + mi.DeclaringType.GetField("Serializer").SetValue(instance, benchmarkCase.Parameters[0].Value); + + var bytes = (byte[])mi.Invoke(instance, null); + return ToHumanReadableSize(bytes.Length); + } + else + { + return "-"; + } + } + + public bool IsAvailable(Summary summary) + { + return true; + } + + public bool IsDefault(Summary summary, BenchmarkCase benchmarkCase) + { + return false; + } + + static string ToHumanReadableSize(long size) + { + return ToHumanReadableSize(new Nullable(size)); + } + + static string ToHumanReadableSize(long? size) + { + if (size == null) return "NULL"; + + double bytes = size.Value; + + if (bytes <= 1024) return bytes.ToString("f2") + " B"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " KB"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " MB"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " GB"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " TB"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " PB"; + + bytes = bytes / 1024; + if (bytes <= 1024) return bytes.ToString("f2") + " EB"; + + bytes = bytes / 1024; + return bytes + " ZB"; + } + } } } diff --git a/benchmark/SerializerBenchmark/Program.cs b/benchmark/SerializerBenchmark/Program.cs index 4ad5bf65..3a504280 100644 --- a/benchmark/SerializerBenchmark/Program.cs +++ b/benchmark/SerializerBenchmark/Program.cs @@ -1,4 +1,5 @@ using Benchmark; +using Benchmark.Models; using BenchmarkDotNet.Running; namespace ConsoleApp1 @@ -8,7 +9,7 @@ namespace ConsoleApp1 static void Main(string[] args) { BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args); - // BenchmarkRunner.Run(); + //BenchmarkRunner.Run(); } } } diff --git a/benchmark/SerializerBenchmark/Serializers/HagarSerializer.cs b/benchmark/SerializerBenchmark/Serializers/HagarSerializer.cs new file mode 100644 index 00000000..06ca15ee --- /dev/null +++ b/benchmark/SerializerBenchmark/Serializers/HagarSerializer.cs @@ -0,0 +1,56 @@ +//using Benchmark.Serializers; +//using System.Buffers; +//using Hagar; +//using Hagar.Buffers; +//using Hagar.Session; +//using Microsoft.Extensions.DependencyInjection; +//using System.IO.Pipelines; + +//public class Hagar_ : SerializerBase +//{ +// readonly ServiceProvider serviceProvider; + +// public Hagar_() +// { +// this.serviceProvider = new ServiceCollection() +// .AddHagar() +// .AddISerializableSupport() +// .AddSerializers(typeof(Hagar_).Assembly) // this assembly +// .BuildServiceProvider(); +// } + +// public override T Deserialize(object input) +// { +// var serializer = serviceProvider.GetRequiredService>(); +// var sessionPool = serviceProvider.GetRequiredService(); + +// var pipe = new Pipe(); +// pipe.Writer.WriteAsync((byte[])input).GetAwaiter().GetResult(); +// pipe.Writer.Complete(); + +// using (var session = sessionPool.GetSession()) +// { +// pipe.Reader.TryRead(out var readResult); +// var reader = new Reader(readResult.Buffer, session); +// var result = serializer.Deserialize(ref reader); +// return result; +// } +// } + +// public override object Serialize(T input) +// { +// var serializer = serviceProvider.GetRequiredService>(); +// var sessionPool = serviceProvider.GetRequiredService(); + +// var pipe = new Pipe(); + +// using (var session = sessionPool.GetSession()) +// { +// var writer = pipe.Writer.CreateWriter(session); +// serializer.Serialize(ref writer, input); +// pipe.Writer.Complete(); +// pipe.Reader.TryRead(out var result); +// return result.Buffer.ToArray(); +// } +// } +//}