Mercurial > projects > ldc
comparison tango/tango/time/StopWatch.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /******************************************************************************* | |
2 | |
3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved | |
4 | |
5 license: BSD style: $(LICENSE) | |
6 | |
7 version: Feb 2007: Initial release | |
8 | |
9 author: Kris | |
10 | |
11 *******************************************************************************/ | |
12 | |
13 module tango.time.StopWatch; | |
14 | |
15 private import tango.core.Exception; | |
16 | |
17 /******************************************************************************* | |
18 | |
19 *******************************************************************************/ | |
20 | |
21 version (Win32) | |
22 { | |
23 private extern (Windows) | |
24 { | |
25 int QueryPerformanceCounter (ulong *count); | |
26 int QueryPerformanceFrequency (ulong *frequency); | |
27 } | |
28 } | |
29 | |
30 version (Posix) | |
31 { | |
32 private import tango.stdc.posix.sys.time; | |
33 } | |
34 | |
35 /******************************************************************************* | |
36 | |
37 Timer for measuring small intervals, such as the duration of a | |
38 subroutine or other reasonably small period. | |
39 --- | |
40 StopWatch elapsed; | |
41 | |
42 elapsed.start; | |
43 | |
44 // do something | |
45 // ... | |
46 | |
47 double i = elapsed.stop; | |
48 --- | |
49 | |
50 The measured interval is in units of seconds, using floating- | |
51 point to represent fractions. This approach is more flexible | |
52 than integer arithmetic since it migrates trivially to more | |
53 capable timer hardware (there no implicit granularity to the | |
54 measurable intervals, except the limits of fp representation) | |
55 | |
56 StopWatch is accurate to the extent of what the underlying OS | |
57 supports. On linux systems, this accuracy is typically 1 us at | |
58 best. Win32 is generally more precise. | |
59 | |
60 There is some minor overhead in using StopWatch, so take that into | |
61 account | |
62 | |
63 *******************************************************************************/ | |
64 | |
65 public struct StopWatch | |
66 { | |
67 private ulong started; | |
68 private static double multiplier = 1.0 / 1_000_000.0; | |
69 | |
70 version (Win32) | |
71 private static double microsecond; | |
72 | |
73 /*********************************************************************** | |
74 | |
75 Start the timer | |
76 | |
77 ***********************************************************************/ | |
78 | |
79 void start () | |
80 { | |
81 started = timer; | |
82 } | |
83 | |
84 /*********************************************************************** | |
85 | |
86 Stop the timer and return elapsed duration since start() | |
87 | |
88 ***********************************************************************/ | |
89 | |
90 double stop () | |
91 { | |
92 return multiplier * (timer - started); | |
93 } | |
94 | |
95 /*********************************************************************** | |
96 | |
97 Return elapsed time since the last start() as microseconds | |
98 | |
99 ***********************************************************************/ | |
100 | |
101 ulong microsec () | |
102 { | |
103 version (Posix) | |
104 return (timer - started); | |
105 | |
106 version (Win32) | |
107 return cast(ulong) ((timer - started) * microsecond); | |
108 } | |
109 | |
110 /*********************************************************************** | |
111 | |
112 Setup timing information for later use | |
113 | |
114 ***********************************************************************/ | |
115 | |
116 static this() | |
117 { | |
118 version (Win32) | |
119 { | |
120 ulong freq; | |
121 | |
122 QueryPerformanceFrequency (&freq); | |
123 microsecond = 1_000_000.0 / freq; | |
124 multiplier = 1.0 / freq; | |
125 } | |
126 } | |
127 | |
128 /*********************************************************************** | |
129 | |
130 Return the current time as an Interval | |
131 | |
132 ***********************************************************************/ | |
133 | |
134 private static ulong timer () | |
135 { | |
136 version (Posix) | |
137 { | |
138 timeval tv; | |
139 if (gettimeofday (&tv, null)) | |
140 throw new PlatformException ("Timer :: linux timer is not available"); | |
141 | |
142 return (cast(ulong) tv.tv_sec * 1_000_000) + tv.tv_usec; | |
143 } | |
144 | |
145 version (Win32) | |
146 { | |
147 ulong now; | |
148 | |
149 if (! QueryPerformanceCounter (&now)) | |
150 throw new PlatformException ("high-resolution timer is not available"); | |
151 | |
152 return now; | |
153 } | |
154 } | |
155 } | |
156 | |
157 | |
158 /******************************************************************************* | |
159 | |
160 *******************************************************************************/ | |
161 | |
162 debug (StopWatch) | |
163 { | |
164 import tango.io.Stdout; | |
165 | |
166 void main() | |
167 { | |
168 StopWatch t; | |
169 t.start; | |
170 | |
171 for (int i=0; i < 100_000_000; ++i) | |
172 {} | |
173 Stdout.format ("{:f9}", t.stop).newline; | |
174 } | |
175 } |