Benchmarking, notes. With benchmarking, we can make smarter decisions. Most of the programs we use every day have been benchmarked many times.
Example. First we see some benchmark loops. This program is what I use for my experiments. Change "_max" depending on the code of each iteration. Start smaller and push the limit up.
Version 1 Each benchmark should have a description in the code, and on the description about the code.
Version 2 This version of the code should be slightly different (but hopefully have the same approximate effect).
using System;
using System.Diagnostics;
const int _max = 1000000;
var s1 = Stopwatch.StartNew();
// Version 1: describe version 1 here.for (int i = 0; i < _max; i++)
{
}
s1.Stop();
var s2 = Stopwatch.StartNew();
// Version 2: describe version 2 here.for (int i = 0; i < _max; i++)
{
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));??? ns Version 1 description
??? ns Version 2 description
Benchmark, 3 loops. Suppose you are feeling ambitious and want to benchmark 3 different versions of code at once. This might be too much, but can be useful at times.
Version 1 In this inner loop, place the code for version 1. It is important to consider whether garbage collection occurs.
Version 2 Another part of the benchmark should be placed here. It is acceptable to increment a counter that is shared between the loops.
Detail Another version is placed here. Occasionally, warming up the JIT and calling methods before the benchmark helps.
Result Having benchmarks carefully labeled, so they can be understood at a glance, is important.
using System;
using System.Diagnostics;
const int m = 1000000;
Stopwatch s1 = Stopwatch.StartNew();
// Version 1: description here.for (int i = 0; i < m; i++)
{
}
s1.Stop();
Stopwatch s2 = Stopwatch.StartNew();
// Version 2: description here.for (int i = 0; i < m; i++)
{
}
s2.Stop();
Stopwatch s3 = Stopwatch.StartNew();
// Version 3: description here.for (int i = 0; i < m; i++)
{
}
s3.Stop();
Console.WriteLine(s1.ElapsedMilliseconds);
Console.WriteLine(s2.ElapsedMilliseconds);
Console.WriteLine(s3.ElapsedMilliseconds);??? Version 1 description
??? Version 2 description
??? Version 3 description
Some problems. The benchmarking code has some problems. The second block sometimes takes less time to execute due to unknown causes.
Tip Repeat and swap two loops if you are doubtful. The first program shown converts the results to nanoseconds.
An example optimization. The Dictionary collection in the base class library is a huge optimization. But developers sometimes write code that results in twice as many lookups.
More complex benchmark. For an example of a more complex benchmark, check the Tuple page. It performs several tests on Tuples to determine how fast tuples are.
Summary. Benchmarking encourages careful thinking about your code. It saves nanoseconds from your software. It also improves the depth of your understanding.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Feb 17, 2023 (edit).