annotate libphobos/src/std/datetime/stopwatch.d @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 // Written in the D programming language
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 Module containing some basic benchmarking and timing functionality.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 For convenience, this module publicly imports $(MREF core,time).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 $(RED Unlike the other modules in std.datetime, this module is not currently
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 publicly imported in std.datetime.package, because the old
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 versions of this functionality which use
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 $(REF TickDuration,core,time) are in std.datetime.package and would
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 conflict with the symbols in this module. After the old symbols have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 gone through the deprecation cycle and have been removed, then this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 module will be publicly imported in std.datetime.package.)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 Authors: Jonathan M Davis and Kato Shoichi
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 Source: $(PHOBOSSRC std/datetime/_stopwatch.d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 module std.datetime.stopwatch;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 public import core.time;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 import std.typecons : Flag;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 Used by StopWatch to indicate whether it should start immediately upon
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 construction.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 If set to $(D AutoStart.no), then the StopWatch is not started when it is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 constructed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 Otherwise, if set to $(D AutoStart.yes), then the StopWatch is started when
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 it is constructed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 alias AutoStart = Flag!"autoStart";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 StopWatch is used to measure time just like one would do with a physical
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 stopwatch, including stopping, restarting, and/or resetting it.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 $(REF MonoTime,core,time) is used to hold the time, and it uses the system's
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 monotonic clock, which is high precision and never counts backwards (unlike
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 the wall clock time, which $(I can) count backwards, which is why
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 $(REF SysTime,std,datetime,systime) should not be used for timing).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 Note that the precision of StopWatch differs from system to system. It is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 impossible for it to be the same for all systems, since the precision of the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 system clock and other system-dependent and situation-dependent factors
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 (such as the overhead of a context switch between threads) varies from system
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 to system and can affect StopWatch's accuracy.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 struct StopWatch
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 Duration t1 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 Duration t2 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 assert(t2 > t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 sw.stop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 Duration t3 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 assert(t3 > t2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 Duration t4 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75 assert(t3 == t4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 Duration t5 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 assert(t5 > t4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 // If stopping or resetting the StopWatch is not required, then
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 // MonoTime can easily be used by itself without StopWatch.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 auto before = MonoTime.currTime;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 // do stuff...
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 auto timeElapsed = MonoTime.currTime - before;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 Constructs a StopWatch. Whether it starts immediately depends on the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 $(LREF AutoStart) argument.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 If $(D StopWatch.init) is used, then the constructed StopWatch isn't
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 running (and can't be, since no constructor ran).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 this(AutoStart autostart) @safe nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 if (autostart)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 assert(sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 assert(sw.peek() > Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 auto sw = StopWatch(AutoStart.no);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118 assert(sw.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 StopWatch sw;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 assert(sw.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 assert(StopWatch.init == StopWatch(AutoStart.no));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 assert(StopWatch.init != StopWatch(AutoStart.yes));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 Resets the StopWatch.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 The StopWatch can be reset while it's running, and resetting it while
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 it's running will not cause it to stop.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 void reset() @safe nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 if (_running)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 _timeStarted = MonoTime.currTime;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142 _ticksElapsed = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 sw.stop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 assert(sw.peek() > Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 sw.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 assert(sw.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 Thread.sleep(msecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 assert(sw.peek() > msecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 immutable before = MonoTime.currTime;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 // Just in case the system clock is slow enough or the system is fast
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 // enough for the call to MonoTime.currTime inside of reset to get
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 // the same that we just got by calling MonoTime.currTime.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 sw.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 assert(sw.peek() < msecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 assert(sw._timeStarted > before);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 assert(sw._timeStarted <= MonoTime.currTime);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 Starts the StopWatch.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 start should not be called if the StopWatch is already running.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 void start() @safe nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 in { assert(!_running, "start was called when the StopWatch was already running."); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 body
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 _running = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 _timeStarted = MonoTime.currTime;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 StopWatch sw;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 assert(sw.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 assert(sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 assert(sw.peek() > Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 Stops the StopWatch.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 stop should not be called if the StopWatch is not running.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 void stop() @safe nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 in { assert(_running, "stop was called when the StopWatch was not running."); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 body
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 _running = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 _ticksElapsed += MonoTime.currTime.ticks - _timeStarted.ticks;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 assert(sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 immutable t1 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 assert(t1 > Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 sw.stop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 immutable t2 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 assert(t2 >= t1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 immutable t3 = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 assert(t2 == t3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 Peek at the amount of time that the the StopWatch has been running.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 This does not include any time during which the StopWatch was stopped but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 does include $(I all) of the time that it was running and not just the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 time since it was started last.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 Calling $(LREF reset) will reset this to $(D Duration.zero).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 Duration peek() @safe const nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 enum hnsecsPerSecond = convert!("seconds", "hnsecs")(1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 immutable hnsecsMeasured = convClockFreq(_ticksElapsed, MonoTime.ticksPerSecond, hnsecsPerSecond);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 return _running ? MonoTime.currTime - _timeStarted + hnsecs(hnsecsMeasured)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 : hnsecs(hnsecsMeasured);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 auto sw = StopWatch(AutoStart.no);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263 assert(sw.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 assert(sw.peek() >= usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 assert(sw.peek() >= usecs(2));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 sw.stop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 immutable stopped = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 assert(sw.peek() == stopped);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 assert(sw.peek() > stopped);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 @safe nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 assert(StopWatch.init.peek() == Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 Sets the total time which the StopWatch has been running (i.e. what peek
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 returns).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 The StopWatch does not have to be stopped for setTimeElapsed to be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 called, nor will calling it cause the StopWatch to stop.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 void setTimeElapsed(Duration timeElapsed) @safe nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 enum hnsecsPerSecond = convert!("seconds", "hnsecs")(1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 _ticksElapsed = convClockFreq(timeElapsed.total!"hnsecs", hnsecsPerSecond, MonoTime.ticksPerSecond);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 _timeStarted = MonoTime.currTime;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 @system nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 import core.thread : Thread;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 StopWatch sw;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 sw.setTimeElapsed(hours(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 // As discussed in MonoTime's documentation, converting between
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 // Duration and ticks is not exact, though it will be close.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 // How exact it is depends on the frequency/resolution of the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 // system's monotonic clock.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 assert(abs(sw.peek() - hours(1)) < usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 Thread.sleep(usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 assert(sw.peek() > hours(1) + usecs(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323 Returns whether this StopWatch is currently running.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325 @property bool running() @safe const pure nothrow @nogc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 return _running;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331 @safe nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333 StopWatch sw;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 sw.start();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 assert(sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 sw.stop();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 assert(!sw.running);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 // We track the ticks for the elapsed time rather than a Duration so that we
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 // don't lose any precision.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 bool _running = false; // Whether the StopWatch is currently running
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348 MonoTime _timeStarted; // The time the StopWatch started measuring (i.e. when it was started or reset).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 long _ticksElapsed; // Total time that the StopWatch ran before it was stopped last.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 /++
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 Benchmarks code for speed assessment and comparison.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 Params:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 fun = aliases of callable objects (e.g. function names). Each callable
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 object should take no arguments.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 n = The number of times each function is to be executed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361 Returns:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 The amount of time (as a $(REF Duration,core,time)) that it took to call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363 each function $(D n) times. The first value is the length of time that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 it took to call $(D fun[0]) $(D n) times. The second value is the length
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365 of time it took to call $(D fun[1]) $(D n) times. Etc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 +/
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 Duration[fun.length] benchmark(fun...)(uint n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 Duration[fun.length] result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 auto sw = StopWatch(AutoStart.yes);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 foreach (i, unused; fun)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 sw.reset();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 foreach (_; 0 .. n)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 fun[i]();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 result[i] = sw.peek();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 ///
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 @safe unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 int a;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 void f0() {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 void f1() { auto b = a; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 void f2() { auto b = to!string(a); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 auto r = benchmark!(f0, f1, f2)(10_000);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 Duration f0Result = r[0]; // time f0 took to run 10,000 times
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394 Duration f1Result = r[1]; // time f1 took to run 10,000 times
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 Duration f2Result = r[2]; // time f2 took to run 10,000 times
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 @safe nothrow unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 import std.conv : to;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 int a;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 void f0() nothrow {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 void f1() nothrow { auto b = to!string(a); }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 auto r = benchmark!(f0, f1)(1000);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 assert(r[0] >= Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 assert(r[1] > Duration.zero);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 assert(r[1] > r[0]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 assert(r[0] < seconds(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 assert(r[1] < seconds(1));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413 @safe nothrow @nogc unittest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415 int f0Count;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 int f1Count;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 int f2Count;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 void f0() nothrow @nogc { ++f0Count; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 void f1() nothrow @nogc { ++f1Count; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 void f2() nothrow @nogc { ++f2Count; }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 auto r = benchmark!(f0, f1, f2)(552);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 assert(f0Count == 552);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 assert(f1Count == 552);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 assert(f2Count == 552);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425 }