Separate setup from tests

This commit is contained in:
Les De Ridder 2019-07-10 02:37:36 +02:00
parent 2be5cd88bc
commit 7b9a338b36
2 changed files with 105 additions and 32 deletions

View File

@ -1,12 +1,13 @@
import util : make, rcarray, StdArray, StdxArray, EMSIArray;
import util;
import std.stdio : stderr, writeln;
import std.datetime : Duration;
import std.meta : AliasSeq;
alias tests = AliasSeq!(testInsert, testInsertDelete, testConcat);
alias containers = AliasSeq!(int[], StdArray!int, EMSIArray!int, rcarray!int, StdxArray!int);
alias tests = AliasSeq!(testInsert, testDelete, testConcat);
alias setupFuns = AliasSeq!(noSetup, makeAndInsert, makeAndInsert);
alias containers = AliasSeq!(int[], StdArray!int, rcarray!int, EMSIArray!int, StdxArray!int);
enum times = 100000;
void testInsert(Container, size_t size = 100)()
@ -15,7 +16,7 @@ void testInsert(Container, size_t size = 100)()
//debug stderr.writeln("Testing inserts on ", typeof(container).stringof);
foreach (i; 0 .. size)
static foreach (i; 0 .. size)
{
container ~= 42;
}
@ -23,17 +24,10 @@ void testInsert(Container, size_t size = 100)()
assert(container.length == size && container[size - 1] == 42);
}
void testInsertDelete(Container, size_t size = 100)()
void testDelete(Container, size_t size = 100)(ref Container container)
{
auto container = make!Container();
//debug stderr.writeln("Testing inserts+deletes on ", typeof(container).stringof);
foreach (i; 0 .. size)
{
container ~= 42;
}
foreach (i; 0 .. size)
{
static if (is(Container : StdxArray!U, U))
@ -53,20 +47,11 @@ void testInsertDelete(Container, size_t size = 100)()
assert(container.length == 0);
}
void testConcat(Container, size_t size = 100)()
void testConcat(Container, size_t size = 100)(ref Container container)
{
auto a = make!Container();
auto b = make!Container();
auto c = container ~ container;
foreach (i; 0 .. size / 2)
{
a ~= 1;
b ~= 2;
}
auto c = a ~ b;
assert(c.length == size);
assert(c.length == size * 2);
}
auto testContainers(Containers...)()
@ -77,10 +62,12 @@ auto testContainers(Containers...)()
Duration[][string] results;
static foreach (test; tests)
{
results[test.stringof] = benchmark!(staticMap!(test, Containers))(times).array;
}
static foreach (i, test; tests)
{{
alias ts = staticMap!(test, Containers);
alias ss = staticMap!(setupFuns[i], Containers);
results[test.stringof] = benchmarkWithSetup!(Transpose!(2, ts, ss))(times).array;
}}
return results;
}
@ -104,14 +91,16 @@ void plotResults(Containers...)(Duration[][string] results)
import plt = matplotlibd.pyplot;
auto i = 0;
foreach (test, testResults; results)
foreach (test; tests)
{
auto testResults = results[test.stringof];
import std.range : iota;
import std.algorithm : map;
import std.array : array;
import std.conv : to;
auto title = test ~ " (" ~ times.to!string ~ " runs)";
auto title = test.stringof ~ " (" ~ times.to!string ~ "x)";
auto x = iota(testResults.length);
auto height = testResults.map!(d => d.total!"msecs").array;
@ -121,18 +110,23 @@ void plotResults(Containers...)(Duration[][string] results)
names ~= Container.stringof;
}
plt.subplot(results.length, 1, ++i);
i++;
//plt.subplot(results.length, 1, i);
plt.clf();
plt.bar(x, height);
plt.xticks(x, names);
plt.ylabel("Time (ms)");
plt.ylim(0, 3000);
plt.title(title);
plt.savefig("out/" ~ i.to!string ~ ".png", ["dpi": 500]);
}
plt.show();
//plt.show();
}
void main()
{
auto results = testContainers!containers;
results.printResults!containers;
results.plotResults!containers;
}

View File

@ -29,3 +29,82 @@ T make(T : StdxArray!U, U)()
{
return T();
}
T makeAndInsert(T, size_t size = 100)()
{
T t = make!T();
static foreach (i; 0 .. size)
{
t ~= 42;
}
return t;
}
T[2] makeAndInsert2(T, size_t totalSize = 100)()
{
T a = make!T();
T b = make!T();
static foreach (i; 0 .. totalSize / 2)
{
a ~= 1;
b ~= 2;
}
return [a, b];
}
import core.time : Duration;
import std.datetime.stopwatch : StopWatch, AutoStart;
Duration[funs.length / 2] benchmarkWithSetup(funs...)(uint n)
{
Duration[funs.length / 2] result;
auto sw = StopWatch(AutoStart.no);
static foreach (i; 0 .. funs.length / 2)
{{
alias fun = funs[i * 2];
alias setup = funs[i * 2 + 1];
sw.reset();
foreach (_; 0 .. n)
{
static if (is(typeof(setup()) == void))
{
sw.start();
fun();
}
else
{
auto setupResult = setup();
sw.start();
fun(setupResult);
}
sw.stop();
}
result[i] = sw.peek();
}}
return result;
}
template Transpose(size_t N, alias A, Args...)
{
import std.meta : AliasSeq;
static assert(N == 2);
static if (Args.length == 1)
{
alias Transpose = AliasSeq!(A, Args[0]);
}
else
{
alias Transpose = AliasSeq!(A, Args[(Args.length - 1) / 2], Transpose!(N, Args[0], Args[1 .. (Args.length - 1) / 2], Args[(Args.length - 1) / 2 + 1 .. $]));
}
}
void noSetup(T)() {}