Skip to content

Instantly share code, notes, and snippets.

@GitHubber10
Created July 30, 2015 08:46
Show Gist options
  • Select an option

  • Save GitHubber10/b4854e4d512b5c5ac61e to your computer and use it in GitHub Desktop.

Select an option

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
[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