1 /+ dub.sdl: 2 dependency "numparse" path=".." 3 +/ 4 module bench.integer; 5 6 import std.datetime.stopwatch; 7 import std : uniform, tuple, Tuple, format, to, stderr; 8 9 import numparse; 10 11 enum Base 12 { 13 bin = 2, 14 oct = 8, 15 dec = 10, 16 hex = 16 17 } 18 19 enum N = 5_000_000; 20 21 string getFormat(Base b, bool longfmt) 22 { 23 final switch (b) 24 { 25 case Base.bin: return longfmt ? "%032b" : "%b"; 26 case Base.oct: return longfmt ? "%011o" : "%o"; 27 case Base.dec: return longfmt ? "%010d" : "%d"; 28 case Base.hex: return longfmt ? "%08x" : "%x"; 29 } 30 } 31 32 float test(Base base)(bool canEmpty=false, bool longFmt=true) 33 { 34 Tuple!(uint, string)[] list; 35 list.length = N; 36 37 immutable fmt = getFormat(base, longFmt); 38 39 foreach (i; 0 .. N) 40 { 41 const v = uniform(0, uint.max); 42 const str = format(fmt, v); 43 list[i] = tuple(cast()v, canEmpty ? (v ? str : "") : str); 44 } 45 46 static void checkValid(uint orig, uint parsed, string str, size_t line=__LINE__) 47 { 48 if (orig == parsed) return; 49 throw new Exception("wrong parse: %s(%d) parsed as %d".format(str, orig, parsed), __FILE__, line); 50 } 51 52 auto t0 = StopWatch(AutoStart.yes); 53 foreach (v; list) 54 { 55 uint tmp; 56 auto err = parseUintNumber!(base)(tmp, v[1]); 57 if (err != ParseError.none) 58 throw new Exception("parse error: %s".format(err)); 59 checkValid(v[0], tmp, v[1]); 60 } 61 t0.stop(); 62 63 auto t1 = StopWatch(AutoStart.yes); 64 foreach (v; list) 65 { 66 uint tmp; 67 if (v[1].length) tmp = v[1].to!uint(cast(int)base); 68 checkValid(v[0], tmp, v[1]); 69 } 70 t1.stop(); 71 72 const t0f = cast(float)t0.peek().total!"hnsecs"; 73 74 stderr.writeln("Base: ", base, " canEmpty: ", canEmpty, " longFmt: ", longFmt); 75 stderr.writeln("numparse: ", t0.peek()); 76 stderr.writeln("std impl: ", t1.peek()); 77 const win = t1.peek().total!"hnsecs" / t0f; 78 stderr.writeln(" win: ", win); 79 return win; 80 } 81 82 void main() 83 { 84 import std : EnumMembers; 85 86 stderr.writeln("number count: ", N); 87 88 float swin = 0; 89 size_t k = 0; 90 91 enum params = 92 [ 93 tuple(true, true), 94 tuple(true, false), 95 tuple(false, false), 96 tuple(false, true), 97 ]; 98 99 foreach (pp; params) 100 { 101 static foreach (b; EnumMembers!Base) 102 { 103 swin += test!b(pp.expand); 104 k++; 105 } 106 } 107 108 stderr.writeln("avg win: ", swin / k); 109 }