From 95e40506db8780c54229cf2afafb913f1088e456 Mon Sep 17 00:00:00 2001 From: Bartosz Sypytkowski Date: Thu, 15 Dec 2016 11:18:39 +0100 Subject: [PATCH 01/13] Perf tests + FAKE script --- Wire.FSharpTestTypes/AssemblyInfo.fs | 2 +- Wire.FSharpTestTypes/Library1.fs | 1 - .../DeserializeCollectionsBenchmark.cs | 207 ++++++ .../DeserializeComplexObjectsBenchmark.cs | 92 +++ .../DeserializeFSharpTypesBenchmark.cs | 147 ++++ ...eserializeImmutableCollectionsBenchmark.cs | 148 ++++ .../DeserializePrimitivesBenchmark.cs | 659 ++++++++++++++++++ Wire.Tests.Performance/PerfTestBase.cs | 78 +++ .../Properties/AssemblyInfo.cs | 2 + .../SerializeCollectionsBenchmark.cs | 116 +++ .../SerializeComplexObjectsBenchmark.cs | 76 ++ .../SerializeFSharpTypesBenchmark.cs | 90 +++ .../SerializeImmutableCollectionsBenchmark.cs | 94 +++ .../SerializePrimitivesBenchmark.cs | 344 +++++++++ .../SerializeCollectionsBenchmark.cs | 104 --- .../SerializeComplexObjectsBenchmark.cs | 58 -- .../SerializeImmutableCollectionsBenchmark.cs | 90 --- .../SerializePrimitivesBenchmark.cs | 250 ------- Wire.Tests.Performance/Types/Cyclic.cs | 16 + .../Wire.Tests.Performance.csproj | 63 +- Wire.Tests.Performance/packages.config | 11 +- Wire.Tests/CollectionTests.cs | 2 +- Wire/Wire.project.lock.json | 88 ++- build.cmd | 2 +- build.fsx | 9 +- build.sh | 2 +- 26 files changed, 2203 insertions(+), 548 deletions(-) create mode 100644 Wire.Tests.Performance/Deserialization/DeserializeCollectionsBenchmark.cs create mode 100644 Wire.Tests.Performance/Deserialization/DeserializeComplexObjectsBenchmark.cs create mode 100644 Wire.Tests.Performance/Deserialization/DeserializeFSharpTypesBenchmark.cs create mode 100644 Wire.Tests.Performance/Deserialization/DeserializeImmutableCollectionsBenchmark.cs create mode 100644 Wire.Tests.Performance/Deserialization/DeserializePrimitivesBenchmark.cs create mode 100644 Wire.Tests.Performance/PerfTestBase.cs create mode 100644 Wire.Tests.Performance/Serialization/SerializeCollectionsBenchmark.cs create mode 100644 Wire.Tests.Performance/Serialization/SerializeComplexObjectsBenchmark.cs create mode 100644 Wire.Tests.Performance/Serialization/SerializeFSharpTypesBenchmark.cs create mode 100644 Wire.Tests.Performance/Serialization/SerializeImmutableCollectionsBenchmark.cs create mode 100644 Wire.Tests.Performance/Serialization/SerializePrimitivesBenchmark.cs delete mode 100644 Wire.Tests.Performance/SerializeCollectionsBenchmark.cs delete mode 100644 Wire.Tests.Performance/SerializeComplexObjectsBenchmark.cs delete mode 100644 Wire.Tests.Performance/SerializeImmutableCollectionsBenchmark.cs delete mode 100644 Wire.Tests.Performance/SerializePrimitivesBenchmark.cs create mode 100644 Wire.Tests.Performance/Types/Cyclic.cs diff --git a/Wire.FSharpTestTypes/AssemblyInfo.fs b/Wire.FSharpTestTypes/AssemblyInfo.fs index 8daefa21..2d28adff 100644 --- a/Wire.FSharpTestTypes/AssemblyInfo.fs +++ b/Wire.FSharpTestTypes/AssemblyInfo.fs @@ -3,7 +3,7 @@ open System open System.Reflection open System.Runtime.InteropServices -[] +[] [] [] [] diff --git a/Wire.FSharpTestTypes/Library1.fs b/Wire.FSharpTestTypes/Library1.fs index 892067ed..20a23b0a 100644 --- a/Wire.FSharpTestTypes/Library1.fs +++ b/Wire.FSharpTestTypes/Library1.fs @@ -47,7 +47,6 @@ module TestQuotations = | 0 | 1 -> 1 | _ -> fib(n-1) + fib(n-2) async { return fib x } @> - module TestMap = diff --git a/Wire.Tests.Performance/Deserialization/DeserializeCollectionsBenchmark.cs b/Wire.Tests.Performance/Deserialization/DeserializeCollectionsBenchmark.cs new file mode 100644 index 00000000..ff1b2376 --- /dev/null +++ b/Wire.Tests.Performance/Deserialization/DeserializeCollectionsBenchmark.cs @@ -0,0 +1,207 @@ +using System.Collections.Generic; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Deserialization +{ + public class ByteArrayDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ByteArrayDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new byte[] { 123, 134, 11, 122, 1 }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark byte array deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Deserialize_ByteArray() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public sealed class StringArrayDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public StringArrayDeserializationBenchmark(ITestOutputHelper output) + : base(output) { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new string[] { "abc", "cbd0", "sdsd4", "4dfg", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark string array deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 650000)] + public void Deserialize_StringArray() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public sealed class DictionaryDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public DictionaryDeserializationBenchmark(ITestOutputHelper output) : base(output) + { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new Dictionary + { + ["abc"] = "aaa", + ["dsdf"] = "asdab", + ["fms0"] = "sdftu" + }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark dictionary deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 130000)] + public void Deserialize_Dictionary() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public sealed class ListDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ListDeserializationBenchmark(ITestOutputHelper output) : base(output) + { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new List { "asdad", "asdabs3", "sfsdf44g", "asdf4r", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark list deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 250000)] + public void Deserialize_StringList() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public sealed class LinkedListDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public LinkedListDeserializationBenchmark(ITestOutputHelper output) : base(output) + { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new LinkedList(new[] { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" })); + } + + [NBenchFact(Skip = "FIXME: some problem with recursion, StackOverflowException")] + [PerfBenchmark( + Description = "Benchmark linked list deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip = "FIXME: some problem with recursion, StackOverflowException")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 80000)] + public void Deserialize_LinkedList() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public sealed class HashSetDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public HashSetDeserializationBenchmark(ITestOutputHelper output) : base(output) + { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new HashSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark hash set deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 50000)] + public void Deserialize_HashSet() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public sealed class SortedSetDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public SortedSetDeserializationBenchmark(ITestOutputHelper output) : base(output) + { } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(new SortedSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark sorted set deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 45000)] + public void Deserialize_SortedSet() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Deserialization/DeserializeComplexObjectsBenchmark.cs b/Wire.Tests.Performance/Deserialization/DeserializeComplexObjectsBenchmark.cs new file mode 100644 index 00000000..12ae30b8 --- /dev/null +++ b/Wire.Tests.Performance/Deserialization/DeserializeComplexObjectsBenchmark.cs @@ -0,0 +1,92 @@ +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Wire.Tests.Performance.Types; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Deserialization +{ + public class StructDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public StructDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(LargeStruct.Create()); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark struct deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1000000)] + public void Deserialize_Struct() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class ClassDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ClassDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(TypicalPersonData.MakeRandom()); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark class deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 180000)] + public void Deserialize_Class() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class CyclicReferenceDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public CyclicReferenceDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + + var a = new CyclicA(); + var b = new CyclicB(); + a.B = b; + b.A = a; + + InitStreamWith(a); + } + + [NBenchFact(Skip="FIXME: Stack overflow exception")] + [PerfBenchmark( + Description = "Benchmark cyclic reference deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip = "FIXME: Stack overflow exception")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4000000)] + public void Deserialize_Cyclic() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Deserialization/DeserializeFSharpTypesBenchmark.cs b/Wire.Tests.Performance/Deserialization/DeserializeFSharpTypesBenchmark.cs new file mode 100644 index 00000000..89a47a7f --- /dev/null +++ b/Wire.Tests.Performance/Deserialization/DeserializeFSharpTypesBenchmark.cs @@ -0,0 +1,147 @@ +using Microsoft.FSharp.Collections; +using Microsoft.FSharp.Core; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Wire.FSharpTestTypes; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Deserialization +{ + public class DiscriminatedUnionDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public DiscriminatedUnionDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(DU2.NewC(DU1.NewB("test", 123))); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark dyscriminated union deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 500000)] + public void Deserialize_DiscriminatedUnion() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class RecordDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public RecordDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + var record = new User( + name: "John Doe", + aref: FSharpOption.Some("ok"), + connections: "test"); + InitStreamWith(record); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark record deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 350000)] + public void Deserialize_Record() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class FSharpMapDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public FSharpMapDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(TestMap.createRecordWithMap); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark F# map deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 120000)] + public void Deserialize_FSharpMap() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class FSharpListDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public FSharpListDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + var list = ListModule.OfArray(new[] { 123, 2342355, 456456467578, 234234, -234281 }); + InitStreamWith(list); + } + + [NBenchFact(Skip = "FIXME: counter is always 0")] + [PerfBenchmark( + Description = "Benchmark F# list deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip = "FIXME: counter is always 0")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4000000)] + public void Deserialize_FSharpList() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class FSharpSetDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public FSharpSetDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + var set = SetModule.OfArray(new[] { 123, 2342355, 456456467578, 234234, -234281 }); + InitStreamWith(set); + } + + [NBenchFact(Skip = "FIXME: counter is always 0")] + [PerfBenchmark( + Description = "Benchmark F# list deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip="FIXME: counter is always 0")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4000000)] + public void Deserialize_FSharpSet() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Deserialization/DeserializeImmutableCollectionsBenchmark.cs b/Wire.Tests.Performance/Deserialization/DeserializeImmutableCollectionsBenchmark.cs new file mode 100644 index 00000000..270cb8c3 --- /dev/null +++ b/Wire.Tests.Performance/Deserialization/DeserializeImmutableCollectionsBenchmark.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Deserialization +{ + public class ImmutableArrayDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ImmutableArrayDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(ImmutableArray.Create(123, 56568, 3445, 568567, 234236, 5821, 2456, 71231)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable array deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 240000)] + public void Deserialize_ImmutableArray() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class ImmutableListDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ImmutableListDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(ImmutableList.Create(123, 56568, 3445, 568567, 234236, 5821, 2456, 71231)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable list deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 230000)] + public void Deserialize_ImmutableList() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class ImmutableHashSetDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ImmutableHashSetDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(ImmutableHashSet.Create(123, 56568, 3445, 568567, 234236, 5821, 2456, 71231)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable hash set deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 120000)] + public void Deserialize_ImmutableHashSet() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class ImmutableSortedSetDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ImmutableSortedSetDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(ImmutableSortedSet.Create(123, 56568, 3445, 568567, 234236, 5821, 2456, 71231)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable sorted set deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 180000)] + public void Deserialize_ImmutableSortedSet() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class ImmutableDictionaryDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ImmutableDictionaryDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(ImmutableDictionary.CreateRange(new Dictionary + { + ["key1"] = 123, + ["key2"] = 1234, + ["key3"] = 12345, + ["key4"] = 123456, + ["key5"] = 1234567, + ["key6"] = 12345678, + ["key7"] = 123456789, + })); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable dictionary deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 75000)] + public void Deserialize_ImmutableDictionary() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Deserialization/DeserializePrimitivesBenchmark.cs b/Wire.Tests.Performance/Deserialization/DeserializePrimitivesBenchmark.cs new file mode 100644 index 00000000..1ece0436 --- /dev/null +++ b/Wire.Tests.Performance/Deserialization/DeserializePrimitivesBenchmark.cs @@ -0,0 +1,659 @@ +using System; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Deserialization +{ + public class ByteDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public ByteDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((byte)120); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Byte deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 9000000)] + public void Deserialize_Byte() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class Int16DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Int16DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((short)12389); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int16 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 7500000)] + public void Deserialize_Int16() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class Int32DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Int32DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(1238919); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int32 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 13000000)] + public void Deserialize_Int32() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class Int64DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Int64DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(93111238919L); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int64 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 11000000)] + public void Deserialize_Int64() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class SByteDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public SByteDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((sbyte)-120); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.SByte deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 17000000)] + public void Deserialize_SByte() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class UInt16DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public UInt16DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((ushort)12389); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt16 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 12000000)] + public void Deserialize_UInt16() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class UInt32DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public UInt32DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((uint)11238919); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt32 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 7000000)] + public void Deserialize_UInt32() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class UInt64DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public UInt64DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((ulong)793111238919L); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt64 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 12000000)] + public void Deserialize_UInt64() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class SingleDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public SingleDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((float)1.21355); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Single deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 6500000)] + public void Deserialize_Single() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class DoubleDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public DoubleDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((double)1.21355); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Double deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 6000000)] + public void Deserialize_Double() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class DecimalDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public DecimalDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith((decimal)1.21355); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Decimal deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 6500000)] + public void Deserialize_Decimal() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class BoolDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public BoolDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(true); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Boolean deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 9000000)] + public void Deserialize_Bool() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class StringDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public StringDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + var s = new string('x', 100); + InitStreamWith(s); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.String deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 3500000)] + public void Deserialize_String() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class GuidDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public GuidDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Guid.NewGuid()); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Guid deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 5500000)] + public void Deserialize_Guid() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class TimeSpanDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public TimeSpanDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(DateTime.Now.TimeOfDay); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.TimeSpan deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1500000)] + public void Deserialize_TimeSpan() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class DateTimeDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public DateTimeDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(DateTime.Now); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.DateTime deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 12000000)] + public void Deserialize_DateTime() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class TypeDeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public TypeDeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(typeof(int)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Type deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 90000)] + public void Deserialize_Type() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount(); + } + } + + public class Tuple1DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple1DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`1 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1100000)] + public void Deserialize_Tuple1() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple2DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple2DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 1234)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`2 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 400000)] + public void Deserialize_Tuple2() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple3DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple3DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 234, 345)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`3 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 350000)] + public void Deserialize_Tuple3() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple4DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple4DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 2345, 3456, 4501)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`4 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 260000)] + public void Deserialize_Tuple4() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple5DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple5DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 2345, 3245, 4561, 746756)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`5 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 220000)] + public void Deserialize_Tuple5() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple6DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple6DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 56568, 3445, 568567, 234236, 5821)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`6 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 175000)] + public void Deserialize_Tuple6() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple7DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple7DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 56568, 3445, 568567, 234236, 5821, 2456)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`7 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 260000)] + public void Deserialize_Tuple7() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } + + public class Tuple8DeserializationBenchmark : PerfTestBase + { +#if !NBENCH + public Tuple8DeserializationBenchmark(ITestOutputHelper output) : base(output) { } +#endif + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + InitStreamWith(Tuple.Create(123, 56568, 3445, 568567, 234236, 5821, 2456, 71231)); + } + + [NBenchFact(Skip = "FIXME: counter is always 0")] + [PerfBenchmark( + Description = "Benchmark System.Tuple`8 deserialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip = "FIXME: counter is always 0")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4000000)] + public void Deserialize_Tuple8() + { + Stream.Position = 0; // don't move it up to Setup, I don't know why it needed here to work + DeserializeAndCount>(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/PerfTestBase.cs b/Wire.Tests.Performance/PerfTestBase.cs new file mode 100644 index 00000000..a429ac4f --- /dev/null +++ b/Wire.Tests.Performance/PerfTestBase.cs @@ -0,0 +1,78 @@ +using System.Diagnostics; +using System.IO; +using System.Runtime.CompilerServices; +using NBench; +using NBench.Sdk; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance +{ + public abstract class PerfTestBase + { + public const string TestCounterName = "CallCounter"; + + /// + /// 100 milliseconds. + /// + public const int StandardRunTime = 100; + + /// + /// 3 iterations. + /// + public const int StandardIterationCount = 3; + + protected MemoryStream Stream; + protected Wire.Serializer Serializer; + protected Counter TestCounter; + private readonly SerializerOptions options; + + protected PerfTestBase(SerializerOptions options = null) + { + this.options = options; + new TestRunner(null).SetProcessPriority(concurrent: false); + } + + protected PerfTestBase(ITestOutputHelper output, SerializerOptions options = null) + { + this.options = null; + + Trace.Listeners.Clear(); + Trace.Listeners.Add(new XunitTraceListener(output)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected void SerializeAndCount(T value) + { + Serializer.Serialize(value, Stream); + TestCounter.Increment(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected void DeserializeAndCount() + { + Serializer.Deserialize(Stream); + TestCounter.Increment(); + } + + protected void InitStreamWith(T value) + { + Serializer.Serialize(value, Stream); + Stream.Position = 0; + } + + [PerfSetup] + public virtual void Setup(BenchmarkContext context) + { + Serializer = options == null ? new Serializer() : new Serializer(options); + Stream = new MemoryStream(); + TestCounter = context.GetCounter(TestCounterName); + } + + [PerfCleanup] + public virtual void Cleanup() + { + Stream?.Dispose(); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Properties/AssemblyInfo.cs b/Wire.Tests.Performance/Properties/AssemblyInfo.cs index 9652e8e0..329d9a34 100644 --- a/Wire.Tests.Performance/Properties/AssemblyInfo.cs +++ b/Wire.Tests.Performance/Properties/AssemblyInfo.cs @@ -1,6 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Xunit; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information @@ -34,3 +35,4 @@ // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/Wire.Tests.Performance/Serialization/SerializeCollectionsBenchmark.cs b/Wire.Tests.Performance/Serialization/SerializeCollectionsBenchmark.cs new file mode 100644 index 00000000..c921da60 --- /dev/null +++ b/Wire.Tests.Performance/Serialization/SerializeCollectionsBenchmark.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Serialization +{ + public class SerializeCollectionsBenchmark : PerfTestBase + { +#if !NBENCH + public SerializeCollectionsBenchmark(ITestOutputHelper output) : base(output, new SerializerOptions(preserveObjectReferences: true, versionTolerance: true)) + { + } +#endif + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark byte array serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 5000000)] + public void Serialize_ByteArray() + { + SerializeAndCount(new byte[] { 123, 134, 11, 122, 1 }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark string array serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1200000)] + public void Serialize_StringArray() + { + SerializeAndCount(new string[] { "abc", "cbd0", "sdsd4", "4dfg", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark dictionary serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 500000)] + public void Serialize_Dictionary() + { + var dictionary = new Dictionary + { + ["abc"] = "aaa", + ["dsdf"] = "asdab", + ["fms0"] = "sdftu" + }; + SerializeAndCount(dictionary); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark list serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 650000)] + public void Serialize_List() + { + SerializeAndCount(new List { "asdad", "asdabs3", "sfsdf44g", "asdf4r", "sfsdf44g" }); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark linked list serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 210000)] + public void Serialize_LinkedList() + { + var list = new LinkedList(new[] { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }); + SerializeAndCount(list); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark hash set serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 170000)] + public void Serialize_HashSet() + { + var set = new HashSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }; + SerializeAndCount(set); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark sorted set serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 110000)] + public void Serialize_SortedSet() + { + var set = new SortedSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }; + SerializeAndCount(set); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Serialization/SerializeComplexObjectsBenchmark.cs b/Wire.Tests.Performance/Serialization/SerializeComplexObjectsBenchmark.cs new file mode 100644 index 00000000..11ee2e7b --- /dev/null +++ b/Wire.Tests.Performance/Serialization/SerializeComplexObjectsBenchmark.cs @@ -0,0 +1,76 @@ +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Wire.Tests.Performance.Types; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Serialization +{ + public class SerializeComplexObjectsBenchmark : PerfTestBase + { + private LargeStruct _testStruct; + private TypicalPersonData _testObject; + private CyclicA _cyclic; + +#if !NBENCH + public SerializeComplexObjectsBenchmark(ITestOutputHelper output) + : base(output, new SerializerOptions(versionTolerance: false, preserveObjectReferences: true)) + { + } +#endif + + public override void Setup(BenchmarkContext context) + { + base.Setup(context); + _testStruct = LargeStruct.Create(); + _testObject = TypicalPersonData.MakeRandom(); + + var a = new CyclicA(); + var b = new CyclicB(); + a.B = b; + b.A = a; + + _cyclic = a; + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark struct serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1300000)] + public void Serialize_Struct() + { + SerializeAndCount(_testStruct); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark big object serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 160000)] + public void Serialize_LargeObject() + { + SerializeAndCount(_testObject); + } + + //TODO: PerfBenchmark.Skip doesn't work + [NBenchFact(Skip = "FIXME: stack overflow")] + [PerfBenchmark( + Description = "Benchmark cyclic reference serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test, + Skip = "FIXME: stack overflow")] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 230000)] + public void Serialize_CyclicReferences() + { + SerializeAndCount(_cyclic); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Serialization/SerializeFSharpTypesBenchmark.cs b/Wire.Tests.Performance/Serialization/SerializeFSharpTypesBenchmark.cs new file mode 100644 index 00000000..27f3c219 --- /dev/null +++ b/Wire.Tests.Performance/Serialization/SerializeFSharpTypesBenchmark.cs @@ -0,0 +1,90 @@ +using Microsoft.FSharp.Collections; +using Microsoft.FSharp.Core; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; +using Wire.FSharpTestTypes; + +namespace Wire.Tests.Performance.Serialization +{ + public class SerializeFSharpTypesBenchmark : PerfTestBase + { +#if !NBENCH + public SerializeFSharpTypesBenchmark(ITestOutputHelper output) : base(output) + { + } +#endif + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark discriminated union serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 900000)] + public void Serialize_DiscriminatedUnion() + { + SerializeAndCount(DU2.NewC(DU1.NewB("test", 123))); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark F# record serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 600000)] + public void Serialize_Record() + { + var record = new User( + name: "John Doe", + aref: FSharpOption.Some("ok"), + connections: "test"); + SerializeAndCount(record); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark F# record with map serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 250)] //FIXME: F# Maps are pretty expensive + public void Serialize_RecordWithMap() + { + var record = TestMap.createRecordWithMap; + SerializeAndCount(record); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark F# list serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 700000)] + public void Serialize_FSharpList() + { + var list = ListModule.OfArray(new[] { 123, 2342355, 456456467578, 234234, -234281 }); + SerializeAndCount(list); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark F# set serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 300000)] + public void Serialize_FSharpSet() + { + var set = SetModule.OfArray(new[] { 123, 2342355, 456456467578, 234234, -234281 }); + SerializeAndCount(set); + } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Serialization/SerializeImmutableCollectionsBenchmark.cs b/Wire.Tests.Performance/Serialization/SerializeImmutableCollectionsBenchmark.cs new file mode 100644 index 00000000..143302b9 --- /dev/null +++ b/Wire.Tests.Performance/Serialization/SerializeImmutableCollectionsBenchmark.cs @@ -0,0 +1,94 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Serialization +{ + public class SerializeImmutableCollectionsBenchmark : PerfTestBase + { +#if !NBENCH + public SerializeImmutableCollectionsBenchmark(ITestOutputHelper output) : base(output) + { + } +#endif + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable string array serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 420000)] + public void Serialize_ImmutableArray() + { + var collection = ImmutableArray.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg", "adafd0xd" }); + SerializeAndCount(collection); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable list serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 200000)] + public void Serialize_ImmutableList() + { + var collection = ImmutableList.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg", "adafd0xd" }); + SerializeAndCount(collection); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable hash set serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 100000)] + public void Serialize_ImmutableHashSet() + { + var collection = ImmutableHashSet.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg", "adafd0xd" }); + SerializeAndCount(collection); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable sorted set serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 100000)] + public void Serialize_ImmutableSortedSet() + { + var collection = ImmutableHashSet.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg", "adafd0xd" }); + SerializeAndCount(collection); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark immutable dictionary serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 90000)] + public void Serialize_ImmutableDictionary() + { + var collection = ImmutableDictionary.CreateRange(new[] + { + new KeyValuePair("key1", "value1"), + new KeyValuePair("key2", "value2"), + new KeyValuePair("key3", "value3"), + new KeyValuePair("key4", "value4"), + new KeyValuePair("key5", "value5"), + }); + SerializeAndCount(collection); + } + } +} diff --git a/Wire.Tests.Performance/Serialization/SerializePrimitivesBenchmark.cs b/Wire.Tests.Performance/Serialization/SerializePrimitivesBenchmark.cs new file mode 100644 index 00000000..dde9d9b0 --- /dev/null +++ b/Wire.Tests.Performance/Serialization/SerializePrimitivesBenchmark.cs @@ -0,0 +1,344 @@ +using System; +using System.Diagnostics; +using System.IO; +using NBench; +using Pro.NBench.xUnit.XunitExtensions; +using Xunit.Abstractions; + +namespace Wire.Tests.Performance.Serialization +{ + public class SerializePrimitivesBenchmark : PerfTestBase + { +#if !NBENCH + public SerializePrimitivesBenchmark(ITestOutputHelper output) : base(output) + { + } +#endif + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Byte serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 5300000)] + public void Serialize_Byte() + { + SerializeAndCount((byte)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int16 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Serialize_Int16() + { + SerializeAndCount((short)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int32 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Serialize_Int32() + { + SerializeAndCount((int)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Int64 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4200000)] + public void Serialize_Int64() + { + SerializeAndCount((long)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.SByte serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 5500000)] + public void Serialize_SByte() + { + SerializeAndCount((sbyte)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt16 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Serialize_UInt16() + { + SerializeAndCount((ushort)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt32 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Serialize_UInt32() + { + SerializeAndCount((uint)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.UInt64 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4200000)] + public void Serialize_UInt64() + { + SerializeAndCount((ulong)123); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Boolean serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 5500000)] + public void Serialize_Boolean() + { + SerializeAndCount(true); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Single serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4500000)] + public void Serialize_Single() + { + SerializeAndCount((float)123.56); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Double serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 4000000)] + public void Serialize_Double() + { + SerializeAndCount((double)123.56); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Decimal serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 2500000)] + public void Serialize_Decimal() + { + SerializeAndCount((decimal)123.56); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.String serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1000000)] + public void Serialize_String() + { + var x = new string('x', 100); + SerializeAndCount(x); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Guid serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 2000000)] + public void Serialize_Guid() + { + SerializeAndCount(Guid.NewGuid()); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.DateTime serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 3800000)] + public void Serialize_DateTime() + { + SerializeAndCount(DateTime.UtcNow); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.TimeSpan serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1800000)] //FIXME: why is this so slower than DateTime? + public void Serialize_TimeSpan() + { + SerializeAndCount(DateTime.UtcNow.TimeOfDay); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`1 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 2000000)] + public void Serialize_Tuple1() + { + SerializeAndCount(Tuple.Create(123)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`2 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1500000)] + public void Serialize_Tuple2() + { + SerializeAndCount(Tuple.Create(123, true)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`3 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1100000)] + public void Serialize_Tuple3() + { + SerializeAndCount(Tuple.Create(123, true, "x")); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`4 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 1000000)] + public void Serialize_Tuple4() + { + SerializeAndCount(Tuple.Create(123, true, "x", 123.3f)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`5 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 750000)] + public void Serialize_Tuple5() + { + SerializeAndCount(Tuple.Create(123, true, "x", 123.3f, "asdasdac")); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`6 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 750000)] + public void Serialize_Tuple6() + { + SerializeAndCount(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`7 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 750000)] + public void Serialize_Tuple7() + { + SerializeAndCount(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false, (byte)0xf)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Tuple`8 serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 700000)] + public void Serialize_Tuple8() + { + SerializeAndCount(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false, (byte)0xf, 1234)); + } + + [NBenchFact] + [PerfBenchmark( + Description = "Benchmark System.Type serialization", + NumberOfIterations = StandardIterationCount, + RunMode = RunMode.Throughput, + RunTimeMilliseconds = StandardRunTime, + TestMode = TestMode.Test)] + [CounterThroughputAssertion(TestCounterName, MustBe.GreaterThan, 550000)] + public void Serialize_Type() + { + SerializeAndCount(typeof(int)); + } + } +} diff --git a/Wire.Tests.Performance/SerializeCollectionsBenchmark.cs b/Wire.Tests.Performance/SerializeCollectionsBenchmark.cs deleted file mode 100644 index 98aad25a..00000000 --- a/Wire.Tests.Performance/SerializeCollectionsBenchmark.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using NBench; - -namespace Wire.Tests.Performance -{ - public class SerializeCollectionsBenchmark - { - #region init - - public const int Iterations = 5; - - private Serializer _serializer; - private MemoryStream _stream; - - [PerfSetup] - public void Setup() - { - _serializer = new Serializer(); - _stream = new MemoryStream(); - } - - [PerfCleanup] - public void Cleanup() - { - _stream.Dispose(); - _stream = null; - _serializer = null; - } - - #endregion - - [PerfBenchmark(Description = "Benchmark byte array serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ByteArray() - { - _serializer.Serialize(new byte[] { 123, 134, 11 }, _stream); - } - - [PerfBenchmark(Description = "Benchmark string array serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_StringArray() - { - _serializer.Serialize(new string[] { "abc", "cbd0", "sdsd4", "4dfg" }, _stream); - } - - [PerfBenchmark(Description = "Benchmark dictionary serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Dictionary() - { - var dictionary = new Dictionary - { - ["abc"] = "aaa", - ["dsdf"] = "asdab" - }; - _serializer.Serialize(dictionary, _stream); - } - - [PerfBenchmark(Description = "Benchmark list serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_List() - { - _serializer.Serialize(new List { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }, _stream); - } - - [PerfBenchmark(Description = "Benchmark linked list serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_LinkedList() - { - var list = new LinkedList(new [] { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }); - _serializer.Serialize(list, _stream); - } - - [PerfBenchmark(Description = "Benchmark hash set serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_HashSet() - { - var set = new HashSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }; - _serializer.Serialize(set, _stream); - } - - [PerfBenchmark(Description = "Benchmark sorted set serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_SortedSet() - { - var set = new SortedSet { "asdad", "asdabs3", "dfsdf9", "asdf4r", "sfsdf44g" }; - _serializer.Serialize(set, _stream); - } - } -} \ No newline at end of file diff --git a/Wire.Tests.Performance/SerializeComplexObjectsBenchmark.cs b/Wire.Tests.Performance/SerializeComplexObjectsBenchmark.cs deleted file mode 100644 index a59a999f..00000000 --- a/Wire.Tests.Performance/SerializeComplexObjectsBenchmark.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.IO; -using NBench; -using Wire.Tests.Performance.Types; - -namespace Wire.Tests.Performance -{ - public class SerializeComplexObjectsBenchmark - { - #region init - - public const int Iterations = 5; - - private Serializer _serializer; - private MemoryStream _stream; - - private LargeStruct _testStruct; - private TypicalPersonData _testPerson; - - [PerfSetup] - public void Setup() - { - _serializer = new Serializer(); - _stream = new MemoryStream(); - _testStruct = LargeStruct.Create(); - _testPerson = TypicalPersonData.MakeRandom(); - } - - [PerfCleanup] - public void Cleanup() - { - _stream.Dispose(); - _stream = null; - _serializer = null; - _testStruct = default(LargeStruct); - _testPerson = null; - } - - #endregion - - [PerfBenchmark(Description = "Benchmark struct serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_LargeStruct() - { - _serializer.Serialize(_testStruct, _stream); - } - - [PerfBenchmark(Description = "Benchmark large object serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_LargeObject() - { - _serializer.Serialize(_testPerson, _stream); - } - } -} \ No newline at end of file diff --git a/Wire.Tests.Performance/SerializeImmutableCollectionsBenchmark.cs b/Wire.Tests.Performance/SerializeImmutableCollectionsBenchmark.cs deleted file mode 100644 index cafaa522..00000000 --- a/Wire.Tests.Performance/SerializeImmutableCollectionsBenchmark.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using NBench; - -namespace Wire.Tests.Performance -{ - public class SerializeImmutableCollectionsBenchmark - { - #region init - - public const int Iterations = 5; - - private Serializer _serializer; - private MemoryStream _stream; - - [PerfSetup] - public void Setup() - { - _serializer = new Serializer(); - _stream = new MemoryStream(); - } - - [PerfCleanup] - public void Cleanup() - { - _stream.Dispose(); - _stream = null; - _serializer = null; - } - - #endregion - - [PerfBenchmark(Description = "Benchmark immutable array serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ImmutableArray() - { - var collection = ImmutableArray.CreateRange(new[] {"abc", "cbd0", "sdsd4", "4dfg"}); - _serializer.Serialize(collection, _stream); - } - - [PerfBenchmark(Description = "Benchmark immutable list serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ImmutableList() - { - var collection = ImmutableList.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg" }); - _serializer.Serialize(collection, _stream); - } - - [PerfBenchmark(Description = "Benchmark immutable hash set serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ImmutableHashSet() - { - var collection = ImmutableHashSet.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg" }); - _serializer.Serialize(collection, _stream); - } - - [PerfBenchmark(Description = "Benchmark immutable sorted set serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ImmutableSortedSet() - { - var collection = ImmutableHashSet.CreateRange(new[] { "abc", "cbd0", "sdsd4", "4dfg" }); - _serializer.Serialize(collection, _stream); - } - - [PerfBenchmark(Description = "Benchmark immutable dictionary serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_ImmutableDictionary() - { - var collection = ImmutableDictionary.CreateRange(new[] - { - new KeyValuePair("key1", "value1"), - new KeyValuePair("key2", "value2"), - new KeyValuePair("key3", "value3"), - new KeyValuePair("key4", "value4"), - }); - _serializer.Serialize(collection, _stream); - } - } -} diff --git a/Wire.Tests.Performance/SerializePrimitivesBenchmark.cs b/Wire.Tests.Performance/SerializePrimitivesBenchmark.cs deleted file mode 100644 index b883a6c4..00000000 --- a/Wire.Tests.Performance/SerializePrimitivesBenchmark.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.IO; -using NBench; - -namespace Wire.Tests.Performance -{ - public class SerializePrimitivesBenchmark - { - #region init - - public const int Iterations = 5; - - private Serializer _serializer; - private MemoryStream _stream; - - [PerfSetup] - public void Setup() - { - _serializer = new Serializer(); - _stream = new MemoryStream(); - } - - [PerfCleanup] - public void Cleanup() - { - _stream.Dispose(); - _stream = null; - _serializer = null; - } - - #endregion - - [PerfBenchmark(Description = "Benchmark System.Byte serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Byte() - { - _serializer.Serialize((byte)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Int16 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Int16() - { - _serializer.Serialize((short)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Int32 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Int32() - { - _serializer.Serialize((int)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Int64 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Int64() - { - _serializer.Serialize((long)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.SByte serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_SByte() - { - _serializer.Serialize((sbyte)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.UInt16 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_UInt16() - { - _serializer.Serialize((ushort)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.UInt32 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_UInt32() - { - _serializer.Serialize((uint)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.UInt64 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_UInt64() - { - _serializer.Serialize((ulong)123, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Boolean serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Boolean() - { - _serializer.Serialize(true, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Single serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Single() - { - _serializer.Serialize((float)123.56, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Double serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Double() - { - _serializer.Serialize((double)123.56, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Decimal serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Decimal() - { - _serializer.Serialize((decimal)123.56, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.String serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_String() - { - var x = new string('x', Iterations); - _serializer.Serialize(x, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Guid serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Guid() - { - _serializer.Serialize(Guid.NewGuid(), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.DateTime serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_DateTime() - { - _serializer.Serialize(DateTime.UtcNow, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.TimeSpan serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_TimeSpan() - { - _serializer.Serialize(DateTime.UtcNow.TimeOfDay, _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`1 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple1() - { - _serializer.Serialize(Tuple.Create(123), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`2 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple2() - { - _serializer.Serialize(Tuple.Create(123, true), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`3 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple3() - { - _serializer.Serialize(Tuple.Create(123, true, "x"), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`4 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple4() - { - _serializer.Serialize(Tuple.Create(123, true, "x", 123.3f), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`5 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple5() - { - _serializer.Serialize(Tuple.Create(123, true, "x", 123.3f, "asdasdac"), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`6 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple6() - { - _serializer.Serialize(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`7 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple7() - { - _serializer.Serialize(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false, (byte)0xf), _stream); - } - - [PerfBenchmark(Description = "Benchmark System.Tuple`8 serialization", - RunMode = RunMode.Iterations, TestMode = TestMode.Test, NumberOfIterations = Iterations)] - [TimingMeasurement] - [ElapsedTimeAssertion(MaxTimeMilliseconds = 300)] - public void Serialize_Tuple8() - { - _serializer.Serialize(Tuple.Create(123, true, "x", 123.3f, "asdasdac", false, (byte)0xf, 1234), _stream); - } - } -} diff --git a/Wire.Tests.Performance/Types/Cyclic.cs b/Wire.Tests.Performance/Types/Cyclic.cs new file mode 100644 index 00000000..697092c9 --- /dev/null +++ b/Wire.Tests.Performance/Types/Cyclic.cs @@ -0,0 +1,16 @@ +using System; + +namespace Wire.Tests.Performance.Types +{ + [Serializable] + public class CyclicA + { + public CyclicB B { get; set; } + } + + [Serializable] + public class CyclicB + { + public CyclicA A { get; set; } + } +} \ No newline at end of file diff --git a/Wire.Tests.Performance/Wire.Tests.Performance.csproj b/Wire.Tests.Performance/Wire.Tests.Performance.csproj index 868d40ce..7152fd85 100644 --- a/Wire.Tests.Performance/Wire.Tests.Performance.csproj +++ b/Wire.Tests.Performance/Wire.Tests.Performance.csproj @@ -1,5 +1,6 @@  + Debug @@ -9,8 +10,11 @@ Properties Wire.Tests.Performance Wire.Tests.Performance - v4.5 + v4.6 512 + + + true @@ -30,8 +34,16 @@ 4 - - ..\packages\NBench.0.3.1\lib\net45\NBench.dll + + ..\packages\FSharp.Core.4.0.1.7-alpha\lib\net40\FSharp.Core.dll + True + + + ..\packages\NBench.0.3.3\lib\net45\NBench.dll + True + + + ..\packages\Pro.NBench.xUnit.1.0.2\lib\net451\Pro.NBench.xUnit.dll True @@ -46,19 +58,47 @@ + + ..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll + True + + + ..\packages\xunit.assert.2.1.0\lib\dotnet\xunit.assert.dll + True + + + ..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll + True + + + ..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll + True + - - - - + + + + + + + + + + + + + + {2d321671-6320-4dd2-b174-2773192d2a5a} + Wire.FSharpTestTypes + {7af8d2b6-9f1f-4a1c-8673-48e533108385} Wire @@ -68,7 +108,16 @@ + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + +