private static void DoSpeedTest <T>( string testGroupName, Func <List <SimpleObject>, List <T> > serializeFunc, Func <List <T>, List <SimpleObject> > deserializeFunc, Func <List <T>, double> getAvgPayload) { var data = new List <T>(); var testGroup = new TestGroup(testGroupName); var serializationTestSummary = testGroup .Plan("Serialization", () => data = serializeFunc(SimpleObjects), TestRuns) .GetResult() .GetSummary(OutcomeFilter); Console.WriteLine(serializationTestSummary); Console.WriteLine("Test Group [{0}] average serialized byte array size is [{1}]", testGroupName, getAvgPayload(data)); var objects = new List <SimpleObject>(); var deserializationTestSummary = testGroup .Plan("Deserialization", () => objects = deserializeFunc(data), TestRuns) .GetResult() .GetSummary(OutcomeFilter); Console.WriteLine(deserializationTestSummary); Console.WriteLine("---------------------------------------------------------\n\n"); }
private static void DoSpeedTest <T>( string testGroupName, List <T> objects, Func <List <T>, List <byte[]> > serializeFunc, Func <List <byte[]>, List <T> > deserializeFunc) { var byteArrays = new List <byte[]>(); var testGroup = new TestGroup(testGroupName); var serializationTestSummary = testGroup .Plan("Serialization", () => byteArrays = serializeFunc(objects), TestRuns) .GetResult() .GetSummary(OutcomeFilter); Console.WriteLine(serializationTestSummary); Console.WriteLine("Test Group [{0}] average serialized byte array size is [{1}]", testGroupName, byteArrays.Average(arr => arr.Length)); var clones = new List <T>(); if (deserializeFunc != null) { var deserializationTestSummary = testGroup .Plan("Deserialization", () => clones = deserializeFunc(byteArrays), TestRuns) .GetResult() .GetSummary(OutcomeFilter); Console.WriteLine(deserializationTestSummary); } Console.WriteLine("--------------------------------------------------------"); }
static List <Result> DoSpeedTest <T, V>(string serializerName, string niceTypeName, Func <T, V> serializeFunc, Func <V, T, dynamic> deserializeFunc, T obj) where T : class where V : class { const int TestRuns = 100; V data = null; var testGroup = new TestGroup(niceTypeName + " - " + serializerName); Console.WriteLine(serializerName); var serializeResult = testGroup .Plan("Serialization", () => data = serializeFunc(obj), TestRuns) .GetResult(); if (serializeResult.Outcomes.Any(o => o.Exception != null)) { throw new Exception("Serialization failed w/ " + serializerName); } Console.WriteLine("\t" + serializeResult.Outcomes.Select(s => s.Elapsed.TotalMilliseconds).Average() + "ms"); var deserializeResult = testGroup .Plan("Deserialization", () => deserializeFunc(data, obj), TestRuns) .GetResult(); if (deserializeResult.Outcomes.Any(o => o.Exception != null)) { throw new Exception("Deserialization failed w/ " + serializerName); } Console.WriteLine("\t" + deserializeResult.Outcomes.Select(s => s.Elapsed.TotalMilliseconds).Average() + "ms"); return (serializeResult.Outcomes.Select( o => new Result { Serializer = serializerName + " (Serialize)", TypeName = niceTypeName, Elapsed = o.Elapsed } ).Concat( deserializeResult.Outcomes.Select( o => new Result { Serializer = serializerName + " (Deserialize)", TypeName = niceTypeName, Elapsed = o.Elapsed } ) ).ToList()); }
unsafe List <MyTestResult> BenchAll <T>(string name, T item, IntPtr ptr, int length, Random random, int testRuns) { var methods = new Benchy <T>[] { Newtonsoft, Jil, ProtoBuf, #if FPBENCH Brianary, #endif CameronismPointer, CameronismStream, CameronismFakeStream, }; var testGroup = new TestGroup(name); return(methods .OrderBy(_ => random.Next()) .Select(method => { var positions = new List <long?>(); var result = new MyTestResult { Case = testGroup.Name, Serializer = method.Method.Name, Lengths = positions, }; Action plan = () => { using (var ms = new UnmanagedMemoryStream((byte *)ptr, 0, length, FileAccess.Write)) { method.Invoke(item, ms); positions.Add(ms.Position); } }; var serializeResult = testGroup .Plan(method.Method.Name, plan, testRuns) .GetResult(); var filter = new SimpleSpeedTester.Core.OutcomeFilters.ExcludeMinAndMaxTestOutcomeFilter(); var summary = serializeResult.GetSummary(filter); result.Summary = summary; positions.Sort(); if (positions.Count > 1 && positions.First() != positions.Last()) { throw new Exception("Inconsistent results from " + method.Method.Name); } return result; }) .ToList()); }
private static void Example4() { // initialize a new test group var testGroup = new TestGroup("Example4"); var sleepIntervals = new[] { 2, 3, 4, 5, 11 }; var index = 0; // plans a test which puts the thread to sleep for 2, 3, 4, 5 and then 11 seconds, zzz.... var test = testGroup.Plan("Test1", () => Thread.Sleep(TimeSpan.FromSeconds(sleepIntervals[index++])), 5); // execute the test runs and get the result var testResult = test.GetResult(); // summaries the result whilst considering all the test outcomes var resultSummaryDefault = testResult.GetSummary(); // alternatively, provide a filter so that when the average execution time is calculated, the min // and max times are not considered var resultSummaryExcludeMinAndMax = testResult.GetSummary(new ExcludeMinAndMaxTestOutcomeFilter()); Console.WriteLine(resultSummaryDefault); /* prints out something along the line of: * * Test Group [Example4], Test [Test1] results summary: * Successes [5] * Failures [0] * Average Exec Time [5000.05438] milliseconds * */ Console.WriteLine(resultSummaryExcludeMinAndMax); /* prints out something along the line of: * * Test Group [Example4], Test [Test1] results summary: * Successes [5] * Failures [0] * Average Exec Time [4000.1766] milliseconds * */ }
private static void Example3() { // initialize a new test group var testGroup = new TestGroup("Example3"); var randomGenerator = new Random(DateTime.UtcNow.Millisecond); // you can also plan a test that runs against some piece of data, it provides // you with a way to track some arbitrary metric as you run your tests var numbers = new List <int>(); var testAction = testGroup.Plan( "Test1", lst => lst.Add(randomGenerator.Next(100)), numbers, 5); // when executed, this test will add 5 random numbers between 0 and 99 to the // 'numbers' list testAction.GetResult(); // this will print the 5 random number, e.g. 15, 7, 4, 9, 38 Console.WriteLine(string.Join(",", numbers.Select(n => n.ToString()))); }
private static void Example3() { // initialize a new test group var testGroup = new TestGroup("Example3"); var randomGenerator = new Random(DateTime.UtcNow.Millisecond); // you can also plan a test that runs against some piece of data, it provides // you with a way to track some arbitrary metric as you run your tests var numbers = new List<int>(); var testAction = testGroup.Plan( "Test1", lst => lst.Add(randomGenerator.Next(100)), numbers, 5); // when executed, this test will add 5 random numbers between 0 and 99 to the // 'numbers' list testAction.GetResult(); // this will print the 5 random number, e.g. 15, 7, 4, 9, 38 Console.WriteLine(string.Join(",", numbers.Select(n => n.ToString()))); }
private static void Example1() { // initialize a new test group var testGroup = new TestGroup("Example1"); // create a test (in the form of an Action delegate) but don't run it yet // when executed, the test will invoke the Action delegate 5 times and time // how long it took each time var test = testGroup.Plan("Test1", () => { }, 5); // calling GetResult() executes the test var testResult = test.GetResult(); // the outcome (how long did it take, was an unhandled exception thrown?) // for each test run is tracked var testOutcomes = testResult.Outcomes; // let's take a look at the TestOutcome object var firstTestOutcome = testOutcomes.First(); var elapsed = firstTestOutcome.Elapsed; // a TimeSpan object var exception = firstTestOutcome.Exception; // null if no exception // you can use the TestResult object to analyse your test, but it's often // useful to get a summary var testResultSummary = testResult.GetSummary(); Console.WriteLine(testResultSummary); /* prints out something along the line of * * Test Group [Example1], Test [Test1] results summary: * Successes [5] * Failures [0] * Average Exec Time [...] milliseconds * */ }
StringBuilder PerformSerializationTests <T>( string nameOfSerializser, T objectToTest, Func <T, byte[]> serializationToPerform, Func <byte[], T> deserializationToPerform, int numberOfRuns = 100, bool skipSerializedOutput = false ) { var sb = new StringBuilder(); sb.AppendLine(); sb.AppendLine(TitleHr); sb.AppendLine($"TESTS USING {nameOfSerializser} ON {typeof(T).Name}"); sb.AppendLine(TitleHr); byte[] serialized = null; try { var testGroup = new TestGroup($"Tests for {nameOfSerializser}"); var serializationTitle = $"+ {nameOfSerializser} Serialization +"; var deserializationTitle = $"+ {nameOfSerializser} Deserialization +"; var serializationTest = testGroup.Plan(serializationTitle, () => serializationToPerform(objectToTest), numberOfRuns); var serializationTestSummary = serializationTest?.GetResult()?.GetSummary(new ExcludeMinAndMaxTestOutcomeFilter()); serialized = serializationToPerform(objectToTest); if (!skipSerializedOutput) { sb.AppendLine("+ Serialized Value +"); sb.AppendLine(Encoding.UTF8.GetString(serialized)); sb.AppendLine(); } var deserialized = deserializationToPerform(serialized); var compareResults = ObjectComparer.Compare(objectToTest, deserialized); var deserializationTest = testGroup.Plan(deserializationTitle, () => deserializationToPerform(serialized), numberOfRuns); var deserializationTestSummary = deserializationTest?.GetResult()?.GetSummary(new ExcludeMinAndMaxTestOutcomeFilter()); sb.AppendLine(serializationTitle); sb.AppendLine(serializationTestSummary?.ToString()); sb.AppendLine(); sb.AppendLine(deserializationTitle); sb.AppendLine(deserializationTestSummary?.ToString()); sb.AppendLine(); sb.AppendLine("+ Serialized Size +"); sb.AppendLine($"{serialized.Length} bytes"); sb.AppendLine(); sb.AppendLine("+ Differences +"); sb.AppendLine(compareResults.DifferencesString); sb.AppendLine(); } catch (Exception ex) { sb.AppendLine("EXPLODED"); sb.AppendLine(ex.ToString()); sb.AppendLine(); } serialized = null; //HACK: I know this is a lie, but we are just doing it to suggest some cleanup GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); return(sb); }
static List <Result> DoSpeedTest <T>(string serializerName, string niceTypeName, Func <T, string> serializeFunc, T obj) where T : class { const int TestRuns = 100; string data = null; var testGroup = new TestGroup(niceTypeName + " - " + serializerName); Console.Write("\t" + serializerName + "... "); var result = testGroup .Plan("Serialization", () => data = serializeFunc(obj), TestRuns) .GetResult(); Console.WriteLine(result.Outcomes.Select(s => s.Elapsed.TotalMilliseconds).Average() + "ms"); #if DEBUG if (serializerName == "Jil") { var equalCheckable = obj is IGenericEquality <T>; if (equalCheckable) { var copy = JsonConvert.DeserializeObject <T>(data); _CheckEquality.MakeGenericMethod(typeof(T)).Invoke(null, new object[] { obj, copy }); } else { var equalCheckableList = typeof(T).IsList(); if (equalCheckableList) { var copy = JsonConvert.DeserializeObject <T>(data); var checkMethod = _CheckEqualityList.MakeGenericMethod(typeof(T).GetListInterface().GetGenericArguments()[0]); checkMethod.Invoke(null, new object[] { obj, copy }); } else { var equalCheckableDict = typeof(T).IsDictionary(); if (equalCheckableDict) { var copy = JsonConvert.DeserializeObject <T>(data); var checkMethod = _CheckEqualityDictionary.MakeGenericMethod(typeof(T).GetDictionaryInterface().GetGenericArguments()[1]); checkMethod.Invoke(null, new object[] { obj, copy }); } else { throw new Exception("Couldn't correctness-check Jil's serialization of a type: " + typeof(T)); } } } } #endif return (result.Outcomes.Select( o => new Result { Serializer = serializerName, TypeName = niceTypeName, Ellapsed = o.Elapsed } ).ToList()); }