Benchmark Dot Net for performance measurement

LAI TOCA
3 min readApr 19, 2019

--

Ref: https://www.nuget.org/packages/BenchmarkDotNet/

Sometimes for any purpose, programmer would like to refactor their existed function(s) for better structure or expect more efficiency execute time/space improvement. Thanks for wonderful toolkit: BenchmarkDotNet provide us a good approach to measure and visualize the result code changed between before and after.

Luckily, I just happened to have chance for enhancement a project that with function for uploading data streaming to IoT hub. For the original logic, the data streaming were send to cloud order by order per record. This took much of time for opening/closing I/O connections for network transportation. So obviously, we could pack data streaming with multiple records under the restriction of packet size (for example 25K bytes per packet) from the hub.

After new solution were came out, we would like to see if it was really better (more fast or…) than original function.

First, create new project with console application and naming it: XXXXX.Business.Benchmark and add reference from business project.

Benchmark console application

Installation topic framework: BenchmarkDotNet.

Package of BenchmarkDotNet

Next created configuration file for BenchmarkDotNet (For the case we just want target function run once due to I/O might consume much time).

// More settings refer to:   https://benchmarkdotnet.org/articles/configs/configs.html
public class CoreConfig : ManualConfig
{
public CoreConfig()
{
Add(Job.Dry
.With(InProcessToolchain.Instance)
.RunOncePerIteration()
.WithIterationCount(1)
.WithLaunchCount(1)
);
}

Created wrapper class to our target service for measurement.

// DataServiceWrapper.cs// Used our customize configuration
[Config(typeof(CoreConfig))] public class DataServiceWrapper
{
private ISupplementDataService _dataService;
private ConfigModel _settings;

// Parameter for benchmark tested
// false: send one record to hub per I/O
// true: package multiple records as one packet to hub
[Params(false, true)]
public bool IsSendViaBatch;
[GlobalSetup]
public void Setup()
{
_dataService = Program.SupplementDataService;
_settings = Program.Settings;
}

[Benchmark(Description = "Uploading file to IoT hub")]
public void InvokeDataSupplementProcess()
{
var path = _settings.AppBaseInfo.DataSupplementPath;
var uri = new Uri(path);
// Read all csv file(s) under directory
var files = Directory.EnumerateFiles(uri.LocalPath,
Constants.SEARCH_TARGET_CSV_PATTERN,
SearchOption.AllDirectories);
// Perform file uploading process to hub
_dataService.SupplementFileByFileProcess(files, path,
_settings.AppBaseInfo.LineSn, IsSendViaBatch);
}
}

Inside program.cs, injected necessary configuration models, target service…etc, and triggered benchmark.

// Program.cs
static void Main(string[] args)
{
var hostBuilder = new HostBuilder()
.ConfigureAppConfiguration((hostContext, config) =>
{
// configure your own configuration here
// ...
})
.ConfigureServices((hostContext, services) =>
{
// Configure service here
services.Configure<ConfigModel>(hostContext.Configuration);
services.AddTransient<ISupplementDataService,
SupplementDataService>();
// ...
}); var host = hostBuilder.Build();
// Run benchmark
BenchmarkRunner.Run<DataServiceWrapper>();

Console.ReadKey();
}

Let’s started our benchmark and see if the result was as expect.

First round we upload only 10 records per file, result as below:

10 records per file

Second round we upload 500 records per file, result as below:

500 records per file

As the benchmark showed that if we adopt new solution (packaged more records as per packet) indeed saving the I/O and network transport time.

The article just demonstrate how easily we could introduce benchmark to our real case. BenchmarkDotNet support multiple run-time (.net framework, .net core…), platform (windows, linux…) for measurement and built-in all kinds of visualize reports for review. If you got interested, go to official website for more detail.

Note that running benchmark need build the project in release mode.

Reference

--

--

LAI TOCA
LAI TOCA

Written by LAI TOCA

Coding for fun. (Either you are running for food or running for being food.)

No responses yet