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