Created
July 30, 2015 08:46
-
-
Save GitHubber10/b4854e4d512b5c5ac61e to your computer and use it in GitHub Desktop.
A simple performance comparison for one or more functions in C#. Ready for usage in LINQPad
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| [TestCode(Name="Test 1")] | |
| public void Test1() { | |
| // Put your test code here | |
| } | |
| [TestCode(Name="Test 2")] | |
| public void Test2() { | |
| // Put your test code here | |
| } | |
| // You can add more tests, if you like | |
| //[TestCode(Name="Test 3")] | |
| //public void Test3() { | |
| // // Put your test code here | |
| //} | |
| // Main entry point | |
| void Main() | |
| { | |
| // Choose number of repetions and iterations | |
| this.RunTests(3, 1000000); | |
| } | |
| #region Private - DO NOT MODIFY! | |
| // Runs the tests - DO NOT MODIFY! | |
| private void RunTests(int repetitions, int iterations) { | |
| TestCode[] testCodes = this.GetTestCodes(); | |
| Stopwatch sw = Stopwatch.StartNew(); | |
| List<TimeSpan> times = new List<TimeSpan>(); | |
| foreach (TestCode testCode in testCodes) { | |
| Console.WriteLine("Testing code '{0}' {1} times. Please stand by...", testCode.Name, repetitions); | |
| for (int t = 0; t < repetitions; t++) { | |
| sw.Restart(); | |
| Random random = new Random(); | |
| for (int i = 0; i < iterations; i++) { | |
| testCode.Code(); | |
| } | |
| sw.Stop(); | |
| testCode.Times.Add(sw.Elapsed); | |
| Console.WriteLine(" Elapsed time {0}: \t{1}", t, testCode.Times[t]); | |
| } | |
| Console.WriteLine(" Average time: \t\t{0}", testCode.Average); | |
| Console.WriteLine(); | |
| } | |
| if (testCodes.Length > 1) { | |
| TestCode fastest = testCodes.Aggregate<TestCode>((min, tc) => (min == null) ? tc : (min.Average > tc.Average ? tc : min)); | |
| Console.WriteLine("Fastest code: '{0}' ({1})", fastest.Name, fastest.Average); | |
| foreach (TestCode other in testCodes.Where(tc => tc != fastest)) { | |
| Console.WriteLine(" Difference to '{0}': {1}", other.Name, fastest.Average - other.Average); | |
| } | |
| } | |
| } | |
| private TestCode[] GetTestCodes() { | |
| List<TestCode> testCodes = new List<TestCode>(); | |
| MethodInfo[] methodInfos = this.GetType().GetMethods(); | |
| foreach (MethodInfo mi in methodInfos) { | |
| TestCodeAttribute testCodeAttr = mi.GetCustomAttributes(false).FirstOrDefault(ca => ca is TestCodeAttribute) as TestCodeAttribute; | |
| if (testCodeAttr != null) { | |
| testCodes.Add(new TestCode() { | |
| Name = testCodeAttr.Name, | |
| Code = new Action(() => mi.Invoke(this, null)) | |
| }); | |
| } | |
| } | |
| return testCodes.ToArray(); | |
| } | |
| [AttributeUsage(AttributeTargets.Method)] | |
| internal class TestCodeAttribute : Attribute { | |
| public string Name {get; set;} | |
| } | |
| internal class TestCode { | |
| public string Name {get; set;} | |
| public Action Code {get; set;} | |
| public List<TimeSpan> Times {get; private set;} | |
| public TimeSpan Average { | |
| get { | |
| if (this.Times != null) { | |
| return TimeSpan.FromMilliseconds(this.Times.Average(t => t.TotalMilliseconds)); | |
| } | |
| return TimeSpan.FromSeconds(0); | |
| } | |
| } | |
| public TestCode() { | |
| this.Times = new List<TimeSpan>(); | |
| } | |
| } | |
| #endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment