tmds / Tmds.LinuxAsync

MIT License
25 stars 3 forks source link

Automate benchmark execution #74

Open antonfirsov opened 4 years ago

antonfirsov commented 4 years ago

The parameter space became large and complex, running benchmarks is real chore now, and it would be even harder on Citrine, where we need to test with bigger ranges of t. To improve our productivity, I'm planning to implement some automation.

Goals:

Possible solutions:

Example usage:

./RunBenchmarks.ps1 --server http://asp-perf-lin:5001 --client "http://asp-perf-load:5002" -e=epoll,uring -o=iothread,inline -t=4..8

This will run 2 * 2 * 5 = 20 benchmarks in total, and save there results in a CSV having the scheme:

e o t RPS CPU% latency
. . . .. .... ......
. . . .. .... ......
. . . .. .... ......

@adamsitnik any concerns/expectations from your side? Preference for C# vs PowerShell?

adamsitnik commented 4 years ago

I am a n00b and I always go 100% C# 🗡

I've written a very small app that parses commands from a file and runs the benchmarks. Everything is hardcoded, but it gives me what I want, you might find it usefull:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace BenchmarkScheduler
{
    class Program
    {
        static void Main(string[] args)
        {
            const string workingDirectory = @"C:\Projects\aspnet_benchmarks\src\BenchmarksDriver";
            const string commandPrefix = @"run -c Release -- --display-output --server http://asp-perf-lin:5001 --client http://asp-perf-load:5002 --repository https://github.com/tmds/Tmds.LinuxAsync.git --project-file test/web/web.csproj --collect-trace";

            foreach (var commandSuffix in File.ReadAllLines(@"C:\Users\adsitnik\source\repos\BenchmarkScheduler\BenchmarkScheduler\commands.txt").Where(x => !string.IsNullOrEmpty(x)))
            {
                Console.WriteLine("```cmd");
                Console.WriteLine(commandSuffix);
                Console.WriteLine("```");

                Console.WriteLine("```log");

                using (var process = Process.Start(new ProcessStartInfo()
                {
                    FileName = "dotnet",
                    Arguments = $"{commandPrefix} {commandSuffix}",
                    WorkingDirectory = workingDirectory,
                    RedirectStandardOutput = true,
                    UseShellExecute = false,
                    CreateNoWindow = true
                }))
                {
                    string line = null;
                    while ((line = process.StandardOutput.ReadLine()) != null)
                    {
                        if (!string.IsNullOrEmpty(line) && !line.StartsWith('[') && !line.StartsWith("failed"))
                        {
                            Console.WriteLine(line);
                        }
                    }

                    if (process.HasExited)
                    {
                        process.WaitForExit();
                    }
                }

                Console.WriteLine("```");
            }
        }
    }
}