1 /// Copyright: Copyright (c) 2017-2020 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module vox.utils.time_measure; 5 6 import std.stdio : writeln, write, writef, writefln; 7 import vox.all; 8 9 struct PerPassTimeMeasurements 10 { 11 TimeMeasurements totalTimes; 12 TimeMeasurements[] passTimes; 13 CompilePassGlobal[] passes; 14 size_t numPasses; // number of passes in the tree of passes 15 16 this(size_t numIters, CompilePassGlobal[] passes) 17 { 18 this.passes = passes; 19 totalTimes = TimeMeasurements(numIters); 20 foreach (passIndex, string name, Duration dur; PassMetaIterator(passes)) ++numPasses; 21 passTimes = new TimeMeasurements[numPasses]; 22 foreach (ref times; passTimes) times = TimeMeasurements(numIters); 23 } 24 25 void onIteration(size_t iterIndex, Duration iterTime) 26 { 27 totalTimes.onIteration(iterIndex, iterTime); 28 foreach (passIndex, string name, Duration dur; PassMetaIterator(passes)) 29 passTimes[passIndex].onIteration(iterIndex, dur); 30 } 31 32 void print() 33 { 34 void printRow(string name, ref TimeMeasurements times) 35 { 36 writef("%- 20s", name); 37 times.print; 38 writeln; 39 } 40 41 writef("Iterations % 5.0s ", scaledNumberFmt(totalTimes.numIters)); 42 totalTimes.printHeader; writeln; 43 foreach (passIndex, string name, Duration dur; PassMetaIterator(passes)) 44 if (name) 45 printRow(name, passTimes[passIndex]); 46 printRow("Total", totalTimes); 47 } 48 49 void printTsv() 50 { 51 void printRow(string name, ref TimeMeasurements times) 52 { 53 writef("%s", name); 54 times.printTsv; 55 writeln; 56 } 57 58 writef("Iterations %s", scaledNumberFmt(totalTimes.numIters)); 59 totalTimes.printHeaderTsv; writeln; 60 foreach (passIndex, string name, Duration dur; PassMetaIterator(passes)) 61 if (name) 62 printRow(name, passTimes[passIndex]); 63 printRow("Total", totalTimes); 64 } 65 } 66 67 struct TimeMeasurements 68 { 69 size_t numIters; 70 Duration[] iterTimes; 71 Duration totalTime; 72 Duration avgTime() { return totalTime/numIters; } 73 Duration minTime = Duration.max; 74 Duration maxTime = Duration.min; 75 76 this(size_t numIters) 77 { 78 this.numIters = numIters; 79 iterTimes = new Duration[numIters]; 80 } 81 82 void onIteration(size_t iterIndex, Duration iterTime) 83 { 84 iterTimes[iterIndex] = iterTime; 85 totalTime += iterTime; 86 minTime = min(iterTime, minTime); 87 maxTime = max(iterTime, maxTime); 88 } 89 90 enum showNumFirstIters = 3; 91 92 void printHeader() 93 { 94 if (numIters == 1) { 95 write(" time"); 96 } else { 97 foreach (i; 0..min(numIters, showNumFirstIters)) 98 writef(" iter %s", i); 99 write(" total avg min max"); 100 } 101 } 102 103 void print() 104 { 105 if (numIters == 1) { 106 writef(" % 6.2ss", scaledNumberFmt(iterTimes[0])); 107 } else { 108 foreach (i; 0..min(numIters, showNumFirstIters)) 109 writef(" % 6.2ss", scaledNumberFmt(iterTimes[i])); 110 writef(" % 6.2ss", scaledNumberFmt(totalTime)); 111 writef(" % 6.2ss", scaledNumberFmt(avgTime)); 112 writef(" % 6.2ss", scaledNumberFmt(minTime)); 113 writef(" % 6.2ss", scaledNumberFmt(maxTime)); 114 } 115 } 116 117 void printHeaderTsv() 118 { 119 if (numIters == 1) { 120 write("\ttime"); 121 } else { 122 foreach (i; 0..min(numIters, showNumFirstIters)) 123 writef("\titer %s", i); 124 write("\ttotal\tavg\tmin\tmax"); 125 } 126 } 127 128 void printTsv() 129 { 130 if (numIters == 1) { 131 writef("\t%ss", scaledNumberFmt(iterTimes[0])); 132 } else { 133 foreach (i; 0..min(numIters, showNumFirstIters)) 134 writef("\t%#ss", scaledNumberFmt(iterTimes[i])); 135 writef("\t%#ss", scaledNumberFmt(totalTime)); 136 writef("\t%#ss", scaledNumberFmt(avgTime)); 137 writef("\t%#ss", scaledNumberFmt(minTime)); 138 writef("\t%#ss", scaledNumberFmt(maxTime)); 139 } 140 } 141 }