110 lines
3.5 KiB
C#
110 lines
3.5 KiB
C#
|
|
//
|
||
|
|
// Copyright (c) 2012-2021 Antmicro
|
||
|
|
//
|
||
|
|
// This file is licensed under the MIT License.
|
||
|
|
// Full license text is available in the LICENSE file.
|
||
|
|
|
||
|
|
using System;
|
||
|
|
using System.IO;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Diagnostics;
|
||
|
|
using Antmicro.Migrant.PerformanceTester.Tests;
|
||
|
|
using Antmicro.Migrant.PerformanceTester.Serializers;
|
||
|
|
using Antmicro.Migrant;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
|
||
|
|
namespace Antmicro.Migrant.PerformanceTester
|
||
|
|
{
|
||
|
|
public class TestRunner
|
||
|
|
{
|
||
|
|
public TestRunner(TestType testType, SerializerType serializerType)
|
||
|
|
{
|
||
|
|
this.testType = testType;
|
||
|
|
serializer = SerializerFactory.Produce(serializerType);
|
||
|
|
}
|
||
|
|
|
||
|
|
public TestResult Run<T>(ITest<T> test)
|
||
|
|
{
|
||
|
|
var stream = new MemoryStream();
|
||
|
|
if(testType == TestType.Serialization)
|
||
|
|
{
|
||
|
|
return Run(
|
||
|
|
() => serializer.Serialize(test.Object, stream),
|
||
|
|
after: () => stream.Seek(0, SeekOrigin.Begin));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
serializer.Serialize(test.Object, stream);
|
||
|
|
return Run(() =>
|
||
|
|
serializer.Deserialize<T>(stream),
|
||
|
|
before: () => stream.Seek(0, SeekOrigin.Begin));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static TestResult Run(Action whatToRun, Action before = null, Action after = null)
|
||
|
|
{
|
||
|
|
before = before ?? new Action(() => {});
|
||
|
|
after = after ?? new Action(() => {});
|
||
|
|
|
||
|
|
PrintProgress("warming up...");
|
||
|
|
for(var i = 0; i < WarmUpRounds; i++)
|
||
|
|
{
|
||
|
|
before();
|
||
|
|
whatToRun();
|
||
|
|
after();
|
||
|
|
}
|
||
|
|
|
||
|
|
var rounds = 0;
|
||
|
|
var results = new List<double>();
|
||
|
|
while(true)
|
||
|
|
{
|
||
|
|
before();
|
||
|
|
results.Add(Measure(whatToRun));
|
||
|
|
after();
|
||
|
|
rounds++;
|
||
|
|
if(rounds < MinimalNumberOfRounds)
|
||
|
|
{
|
||
|
|
PrintProgress(string.Format("Round {0}.", rounds));
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
var average = results.Skip(results.Count - MinimalNumberOfRounds).Average();
|
||
|
|
var deviation = results.Skip(results.Count - MinimalNumberOfRounds).StandardDeviation();
|
||
|
|
var percentDeviation = deviation/average;
|
||
|
|
PrintProgress(string.Format("Round {1}, {0:#0.#}% deviation.", percentDeviation*100.0, rounds));
|
||
|
|
if(percentDeviation < DesiredDeviation)
|
||
|
|
{
|
||
|
|
PrintProgress("done.");
|
||
|
|
Console.WriteLine();
|
||
|
|
return new TestResult(average, deviation);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static double Measure(Action whatToRun)
|
||
|
|
{
|
||
|
|
var stopwatch = Stopwatch.StartNew();
|
||
|
|
whatToRun();
|
||
|
|
stopwatch.Stop();
|
||
|
|
return stopwatch.Elapsed.TotalSeconds;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void PrintProgress(string what)
|
||
|
|
{
|
||
|
|
Console.CursorLeft = 0;
|
||
|
|
Console.Write(Enumerable.Repeat(" ", Console.BufferWidth - 1).Aggregate((x, y) => x + y));
|
||
|
|
Console.CursorLeft = 0;
|
||
|
|
Console.Write("Running... {0}", what);
|
||
|
|
}
|
||
|
|
|
||
|
|
private readonly TestType testType;
|
||
|
|
private readonly ISerializer serializer;
|
||
|
|
|
||
|
|
private const int WarmUpRounds = 2;
|
||
|
|
private const int MinimalNumberOfRounds = 7;
|
||
|
|
private const double DesiredDeviation = 0.05;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|