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 }