Alex Peta Logo
Alex Peta. technical blog


Mar 25, 2012

Y U No test speed code with BenchmarkNET

by Alex Peta
3.4K
views
0
comm
3
votes
1
tracks

The question for today is “What do you do when you need to test code speed? “. You could start the old fashioned way, adding DateTime variables all over the place and make the difference between them.

But there is something out there much more flexible, a tool named "Benchmark.NET”, a open source project written by my friend Andrei Rinea. You can read the whole blog post here.

To write a quick example on this I will use my old code written back in December for our SecretSanta extraction. Its not the most complex piece of code to test, but its still a valid example because if you take a look at it you will notice that the algorithm complexity is variable.

I will make a couple of changes to my old code. First , I will start by using a SecretSanta class rather then writing the whole piece of code in a Console Application Main method:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BenchmarkNet;

namespace SecretSantaWithBenchmark
{
public class SecretSanta
{
private List<string> peopleToMatch {get;set;}
private List<string> copyOfPeople { get; set; }
private List<int> excludedPosibilities { get; set; }

public Dictionary<string ,string > Results {get;set;}

public SecretSanta(List<string> users)
{
peopleToMatch = users;
copyOfPeople = users;
}

[BenchmarkedThis(BenchmarkNet.BenchmarkType.Sequential,"25-MAR-2012",1,"00:00:00.0014501",0,"Initial test")]
public void Start()
{
do
{
Results = new Dictionary<string, string>();
excludedPosibilities = new List<int>();


foreach (string person in peopleToMatch)
{
var personPosibilites = GetPosibilities(person);
var rand = (new Random()).Next(0, personPosibilites.Count);
Results.Add(person, copyOfPeople[personPosibilites[rand]]);
excludedPosibilities.Add(personPosibilites[rand]);
}
}
while (!TestResults());
}


private List<int> GetPosibilities(string current_check)
{
List<int> return_posibilities = new List<int>();
for (int i = 0; i &lt; copyOfPeople.Count; i++)
{
if (copyOfPeople[i] != current_check && !excludedPosibilities.Contains(i))
return_posibilities.Add(i);
}
return return_posibilities;
}

private bool TestResults()
{
foreach (string person in peopleToMatch)
{
if (Results[person] == person)
return false;
}
return true;
}

public override string ToString()
{
StringBuilder sb = new StringBuilder();
foreach(var person in Results.Keys)
{
sb.Append(string.Format("{0} will get a present for {1}",person.ToUpper(),Results[person].ToUpper())).Append(Environment.NewLine);
}
return sb.ToString();
}

}
}

The logic is mostly the same,  no huge difference in the logic.

The code testing will be done in our Main method :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using BenchmarkNet;

namespace SecretSantaWithBenchmark
{
class Program
{
static void Main(string[] args)
{
List<string> data = new List<string> { "claudiu@email.com","raluca@email.com",
"alex@email.com","madalina@email.com",
"diana@email.com","mihaela@email.com",
"georgeta@email.com" ,"maria@email.com" ,
"adriana@email.com","valentina@email.com" ,
"iulia@email.com","luciana@email.com" ,
"elena@email.com","amalia@email.com" ,"vava@email.com" };

SecretSanta s1 = new SecretSanta(data);

var b1 = Benchmark.Sequential(() =&gt; s1.Start() );

Console.WriteLine("Santa results:"+Environment.NewLine);
Console.WriteLine("-----------------------------");
Console.WriteLine(s1.ToString() + Environment.NewLine);
Console.WriteLine("-----------------------------");
Console.WriteLine(b1.ToString());

}
}
}

All I needed to to in order to test the Start method of the SecretSanta class was to call the Benchmark.Sequential() method, that accepts a Action() and optional number of iterations the default being 1.

Additionally, if you wish to add the test results to the method, you can do this via the BenchmarkThis attribute, and can also include a SVN commit number.

And finally you can download the Visual Studion solution here.

If you liked it, share it:

Trackbacks

alexpeta | | test trackback...
comments powered by Disqus
Content (c) 2011-2014 . All Rights Reserved. The views expressed on this blog are my own and do not necessarily reflect the views of my employer. Logo design - Catalin Boroi - efingo.com.
Creative Commons License
This work by Alex Peta is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
Based on a work at http://alexpeta.ro.
All source code on this site is licensed under the MIT license.