Mercurial > projects > ldc
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tango/tango/time/StopWatch.d Fri Jan 11 17:57:40 2008 +0100 @@ -0,0 +1,175 @@ +/******************************************************************************* + + copyright: Copyright (c) 2007 Kris Bell. All rights reserved + + license: BSD style: $(LICENSE) + + version: Feb 2007: Initial release + + author: Kris + +*******************************************************************************/ + +module tango.time.StopWatch; + +private import tango.core.Exception; + +/******************************************************************************* + +*******************************************************************************/ + +version (Win32) +{ + private extern (Windows) + { + int QueryPerformanceCounter (ulong *count); + int QueryPerformanceFrequency (ulong *frequency); + } +} + +version (Posix) +{ + private import tango.stdc.posix.sys.time; +} + +/******************************************************************************* + + Timer for measuring small intervals, such as the duration of a + subroutine or other reasonably small period. + --- + StopWatch elapsed; + + elapsed.start; + + // do something + // ... + + double i = elapsed.stop; + --- + + The measured interval is in units of seconds, using floating- + point to represent fractions. This approach is more flexible + than integer arithmetic since it migrates trivially to more + capable timer hardware (there no implicit granularity to the + measurable intervals, except the limits of fp representation) + + StopWatch is accurate to the extent of what the underlying OS + supports. On linux systems, this accuracy is typically 1 us at + best. Win32 is generally more precise. + + There is some minor overhead in using StopWatch, so take that into + account + +*******************************************************************************/ + +public struct StopWatch +{ + private ulong started; + private static double multiplier = 1.0 / 1_000_000.0; + + version (Win32) + private static double microsecond; + + /*********************************************************************** + + Start the timer + + ***********************************************************************/ + + void start () + { + started = timer; + } + + /*********************************************************************** + + Stop the timer and return elapsed duration since start() + + ***********************************************************************/ + + double stop () + { + return multiplier * (timer - started); + } + + /*********************************************************************** + + Return elapsed time since the last start() as microseconds + + ***********************************************************************/ + + ulong microsec () + { + version (Posix) + return (timer - started); + + version (Win32) + return cast(ulong) ((timer - started) * microsecond); + } + + /*********************************************************************** + + Setup timing information for later use + + ***********************************************************************/ + + static this() + { + version (Win32) + { + ulong freq; + + QueryPerformanceFrequency (&freq); + microsecond = 1_000_000.0 / freq; + multiplier = 1.0 / freq; + } + } + + /*********************************************************************** + + Return the current time as an Interval + + ***********************************************************************/ + + private static ulong timer () + { + version (Posix) + { + timeval tv; + if (gettimeofday (&tv, null)) + throw new PlatformException ("Timer :: linux timer is not available"); + + return (cast(ulong) tv.tv_sec * 1_000_000) + tv.tv_usec; + } + + version (Win32) + { + ulong now; + + if (! QueryPerformanceCounter (&now)) + throw new PlatformException ("high-resolution timer is not available"); + + return now; + } + } +} + + +/******************************************************************************* + +*******************************************************************************/ + +debug (StopWatch) +{ + import tango.io.Stdout; + + void main() + { + StopWatch t; + t.start; + + for (int i=0; i < 100_000_000; ++i) + {} + Stdout.format ("{:f9}", t.stop).newline; + } +}