collections-benchmark/source/app.d

171 lines
4.0 KiB
D
Raw Normal View History

2019-07-10 02:37:36 +02:00
import util;
2019-07-09 23:26:20 +02:00
import std.stdio : stderr, writeln;
import std.datetime : Duration;
2019-07-09 23:26:20 +02:00
2019-07-10 00:46:42 +02:00
import std.meta : AliasSeq;
2019-07-10 02:59:37 +02:00
alias tests = AliasSeq!(testInsert, testDelete, testConcat, testMixed);
alias setupFuns = AliasSeq!(noSetup, makeAndInsert, makeAndInsert, noSetup);
enum testNames = ["100 inserts", "100 deletes", "Concat", "Mixed"];
2019-07-10 02:37:36 +02:00
alias containers = AliasSeq!(int[], StdArray!int, rcarray!int, EMSIArray!int, StdxArray!int);
2019-07-10 02:59:37 +02:00
enum containerNames = ["[]", "Phobos Array", "rcarray", "EMSI Array", "stdx array"];
2019-07-10 00:46:42 +02:00
enum times = 100000;
void testInsert(Container, size_t size = 100)()
2019-07-09 23:26:20 +02:00
{
auto container = make!Container();
2019-07-10 02:37:36 +02:00
static foreach (i; 0 .. size)
2019-07-09 23:26:20 +02:00
{
container ~= 42;
}
2019-07-10 00:46:42 +02:00
assert(container.length == size && container[size - 1] == 42);
2019-07-09 23:26:20 +02:00
}
2019-07-10 02:37:36 +02:00
void testDelete(Container, size_t size = 100)(ref Container container)
2019-07-09 23:26:20 +02:00
{
2019-07-10 00:46:42 +02:00
foreach (i; 0 .. size)
2019-07-09 23:26:20 +02:00
{
static if (is(Container : StdxArray!U, U))
{
container.forceLength(container.length - 1);
}
else static if (is(Container : EMSIArray!U, U))
{
container.removeBack();
}
else
{
container.length = container.length - 1;
}
}
assert(container.length == 0);
}
2019-07-10 02:37:36 +02:00
void testConcat(Container, size_t size = 100)(ref Container container)
2019-07-09 23:26:20 +02:00
{
2019-07-10 02:37:36 +02:00
auto c = container ~ container;
2019-07-09 23:26:20 +02:00
2019-07-10 02:37:36 +02:00
assert(c.length == size * 2);
2019-07-10 00:46:42 +02:00
}
2019-07-09 23:26:20 +02:00
2019-07-10 02:59:37 +02:00
void testMixed(Container)()
{
auto container = make!Container();
static foreach (i; 0 .. 50)
{
container ~= 42;
}
static foreach (i; 0 .. 25)
{{
static if (is(Container : StdxArray!U, U))
{
container.forceLength(container.length - 1);
}
else static if (is(Container : EMSIArray!U, U))
{
container.removeBack();
}
else
{
container.length = container.length - 1;
}
}}
static foreach (i; 0 .. 25)
{{
container ~= 42;
container ~= 42;
static if (is(Container : StdxArray!U, U))
{
container.forceLength(container.length - 2);
}
else static if (is(Container : EMSIArray!U, U))
{
container.removeBack();
container.removeBack();
}
else
{
container.length = container.length - 2;
}
}}
assert(container.length == 25 && container[24 - 1] == 42);
}
2019-07-10 00:46:42 +02:00
auto testContainers(Containers...)()
2019-07-09 23:26:20 +02:00
{
import std.datetime.stopwatch : benchmark;
import std.meta : staticMap;
2019-07-10 00:46:42 +02:00
import std.array : array;
2019-07-09 23:26:20 +02:00
2019-07-10 02:59:37 +02:00
Duration[][] results;
2019-07-09 23:26:20 +02:00
2019-07-10 02:37:36 +02:00
static foreach (i, test; tests)
{{
alias ts = staticMap!(test, Containers);
alias ss = staticMap!(setupFuns[i], Containers);
2019-07-10 02:59:37 +02:00
results ~= benchmarkWithSetup!(Transpose!(2, ts, ss))(times).array;
2019-07-10 02:37:36 +02:00
}}
2019-07-09 23:26:20 +02:00
return results;
}
2019-07-10 02:59:37 +02:00
void printResults(Containers...)(Duration[][] results)
{
2019-07-10 02:59:37 +02:00
static foreach (i, test; tests)
2019-07-09 23:26:20 +02:00
{
import std.stdio : writeln;
writeln(test.stringof, ":");
2019-07-10 02:59:37 +02:00
static foreach (j, Container; Containers)
2019-07-09 23:26:20 +02:00
{
2019-07-10 02:59:37 +02:00
writeln("\t", Container.stringof, ": ", results[i][j]);
2019-07-09 23:26:20 +02:00
}
}
}
2019-07-10 02:59:37 +02:00
void plotResults(Containers...)(Duration[][] results)
2019-07-09 23:26:20 +02:00
{
2019-07-10 00:46:42 +02:00
import plt = matplotlibd.pyplot;
2019-07-10 02:59:37 +02:00
foreach (i, test; tests)
2019-07-10 00:46:42 +02:00
{
2019-07-10 02:59:37 +02:00
auto testResults = results[i];
2019-07-10 02:37:36 +02:00
2019-07-10 00:46:42 +02:00
import std.range : iota;
import std.algorithm : map;
import std.array : array;
import std.conv : to;
2019-07-10 02:59:37 +02:00
auto title = testNames[i] ~ " (" ~ times.to!string ~ " runs)";
2019-07-10 00:46:42 +02:00
auto x = iota(testResults.length);
auto height = testResults.map!(d => d.total!"msecs").array;
2019-07-10 02:37:36 +02:00
plt.clf();
2019-07-10 00:46:42 +02:00
plt.bar(x, height);
2019-07-10 02:59:37 +02:00
plt.xticks(x, containerNames);
2019-07-10 00:46:42 +02:00
plt.ylabel("Time (ms)");
2019-07-10 02:37:36 +02:00
plt.ylim(0, 3000);
2019-07-10 00:46:42 +02:00
plt.title(title);
2019-07-10 02:37:36 +02:00
plt.savefig("out/" ~ i.to!string ~ ".png", ["dpi": 500]);
2019-07-10 00:46:42 +02:00
}
}
void main()
{
auto results = testContainers!containers;
2019-07-10 02:37:36 +02:00
results.printResults!containers;
2019-07-10 00:46:42 +02:00
results.plotResults!containers;
2019-07-09 23:26:20 +02:00
}