1 module bench;
2 
3 
4 alias Func = int function(int iter);
5 
6 struct Measurement {
7     ulong singleNSecs;
8     ulong[] multiNSecs;
9     ulong iters;
10 
11     @property double singlePerSec() const {
12         return iters * 1_000_000_000 / cast(double)singleNSecs;
13     }
14     @property double multiPerSec() const {
15         double sum=0;
16         foreach(nsecs; multiNSecs) {
17             sum += iters * 1_000_000_000 / cast(double)nsecs;
18         }
19         return sum / multiNSecs.length;
20     }
21 }
22 
23 Measurement measure(Func f, const int iter)
24 {
25     import std.datetime.stopwatch : StopWatch;
26     import std.parallelism : parallel, totalCPUs;
27 
28     Measurement mes;
29 
30     {
31         StopWatch sw;
32         sw.start();
33         mes.iters = f(iter);
34         sw.stop();
35         mes.singleNSecs = sw.peek.total!"nsecs";
36     }
37 
38     mes.multiNSecs = new ulong[ 2 * totalCPUs ];
39     foreach (ref nsecs; parallel(mes.multiNSecs)) {
40         StopWatch sw;
41         sw.start();
42         f(iter);
43         sw.stop();
44         nsecs = sw.peek.total!"nsecs";
45     }
46     return mes;
47 }
48 
49 void benchmark(string name, string dc, string cc, Func gfxF, Func gl3nF, Func glmF, const int iter)
50 {
51     const gfx = measure(gfxF, iter);
52     const gl3n = measure(gl3nF, iter);
53     const glm = measure(glmF, iter);
54 
55     import std.stdio : writefln;
56     writefln("Benchmark: %s", name);
57     writefln("%16s\t%16s\t%16s\t%16s", "Lib", "gfx:math", "gl3n", "glm");
58     writefln("%16s\t%16s\t%16s\t%16s", "Compiler", dc, dc, cc);
59     writefln("%16s\t%16s\t%16s\t%16s", "Iter/s single", gfx.singlePerSec, gl3n.singlePerSec, glm.singlePerSec);
60     writefln("%16s\t%16s\t%16s\t%16s", "Iter/s parallel", gfx.multiPerSec, gl3n.multiPerSec, glm.multiPerSec);
61     writefln("");
62 }