1 module bench;
2 
3 
4 alias Func = int function();
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)
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();
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();
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)
50 {
51     const gfx = measure(gfxF);
52     const gl3n = measure(gl3nF);
53     const glm = measure(glmF);
54 
55 
56     import std.stdio : writefln;
57     writefln("Benchmark: %s", name);
58     writefln("%20s\t%20s\t%20s\t%20s", "Lib", "gfx:math", "gl3n", "glm");
59     writefln("%20s\t%20s\t%20s\t%20s", "Compiler", dc, dc, cc);
60     writefln("%20s\t%20s\t%20s\t%20s", "Iter/s single", gfx.singlePerSec, gl3n.singlePerSec, glm.singlePerSec);
61     writefln("%20s\t%20s\t%20s\t%20s", "Iter/s parallel", gfx.multiPerSec, gl3n.multiPerSec, glm.multiPerSec);
62     writefln("");
63 }