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 }