Time-Stopwatch-1.00/0042755000175000001450000000000007266423250013413 5ustar iltzuiltzuTime-Stopwatch-1.00/Makefile.PL0100644000175000001450000000073707246216422015366 0ustar iltzuiltzuuse ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Time::Stopwatch', 'VERSION_FROM' => 'Stopwatch.pm', 'PREREQ_PM' => {}, # Time::HiRes is recommended ($] < 5.005 ? () : (ABSTRACT_FROM => 'Stopwatch.pm', AUTHOR => 'Ilmari Karonen ')), 'dist' => {COMPRESS => 'gzip', SUFFIX => 'gz'} ); Time-Stopwatch-1.00/Stopwatch.pm0100644000175000001450000001165507266422632015733 0ustar iltzuiltzupackage Time::Stopwatch; $VERSION = '1.00'; # POD documentation after __END__ below use strict; use constant HIRES => eval { local $SIG{__DIE__}; require Time::HiRes }; sub TIESCALAR { my $pkg = shift; my $time = (HIRES ? Time::HiRes::time() : time()) - (@_ ? shift() : 0); bless \$time, $pkg; } sub FETCH { (HIRES ? Time::HiRes::time() : time()) - ${$_[0]}; } sub STORE { ${$_[0]} = (HIRES ? Time::HiRes::time() : time()) - $_[1]; } "That's all, folks!" __END__ =head1 NAME Time::Stopwatch - Use tied scalars as timers =head1 SYNOPSIS use Time::Stopwatch; tie my $timer, 'Time::Stopwatch'; do_something(); print "Did something in $timer seconds.\n"; my @times = map { $timer = 0; do_something_else(); $timer; } 1 .. 5; =head1 DESCRIPTION The Time::Stopwatch module provides a convenient interface to timing functions through tied scalars. From the point of view of the user, scalars tied to the module simply increase their value by one every second. Using the module should mostly be obvious from the synopsis. You can provide an initial value for the timers either by assigning to them or by passing the value as a third argument to tie(). If you have the module Time::HiRes installed, the timers created by Time::Stopwatch will automatically count fractional seconds. Do I assume that the values of the timers are always integers. You may test the constant C to find out whether high resolution timing is enabled. =head2 A note on timing short intervals Time::Stopwatch is primarily designed for timing moderately long intervals (i.e. several seconds), where the overhead imposed by the tie() interface does not matter. With Time::HiRes installed, it can nonetheless be used for even microsecond timing, provided that appropriate care is taken. =over 4 =item * Explicitly initialize the timer by assignment. The first measurement taken before resetting the timer will be a few microseconds longer due to the overhead of the tie() call. =item * B subtract the overhead of the timing code. This is true in general even if you're not using Time::Stopwatch. (High-level benchmarking tools like Benchmark.pm do this automatically.) See the code example below. =item * Take as many measurements as you can to minimize random errors. The Statistics::Descriptive module may be useful for analyzing the data. This advice is also true for all benchmarking. =item * Remember that a benchmark measures the time take to run the benchmark. Any generalizations to real applications may or may not be valid. If you want real world data, profile the real code in real use. =back The following sample code should give a relatively reasonable measurement of a the time taken by a short operation: use Time::HiRes; # high resolution timing required use Time::Stopwatch; use Statistics::Descriptive; my $stat = Statistics::Descriptive::Sparse->new(); tie my $time, 'Time::Stopwatch'; # code timer tie my $wait, 'Time::Stopwatch'; # loop timer while ($wait < 60) { # run for one minute my $diff = 0; $time = 0; do_whatever(); $diff += $time; $time = 0; $diff -= $time; $stat->add_data($diff); } print("count: ", $stat->count(), " iterations\n", "mean: ", $stat->mean(), " seconds\n", "s.d.: ", $stat->standard_deviation(), " seconds\n"); Note that the above code includes the time of the subroutine call in the measurement. =head1 BUGS Since tied scalars do not (yet?) support atomic modification, use of operators like C<$t++> or C<$t *= 2> on timers will cause them to lose the time it takes to fetch, modify and store the value. I I be able to get around this by overloading the return value of C, but I doubt if it's worth the trouble. Just don't do that. There is no way to force low-resolution timing if Time::HiRes has been installed. I'm not sure why anyone would want to, since int() will do just fine if you want whole seconds, but still.. =head1 CHANGE LOG =over 4 =item 1.00 (15 Mar 2001) Explicitly localized C<$SIG{__DIE__}> when testing for Time::HiRes availability. Added "A note on timing short intervals" to the POD documentation. Bumped version to 1, no longer beta. =item 0.03 (27 Feb 2001) Modified tests to give more information, reduced subsecond accuracy test to 1/10 seconds to allow for inaccurate select() implementations. Tweaked synopsis and README. =back =head1 SEE ALSO Time::HiRes, L For a higher-level approach to timing, try (among others) the modules Time::SoFar, Devel::Timer, or Benchmark. Also see the profiling modules Devel::DProf, Devel::SmallProf and Devel::OpProf. =head1 AUTHORS Copyright 2000-2001, Ilmari Karonen. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Address bug reports and comments to: perl@itz.pp.sci.fi =cut Time-Stopwatch-1.00/test.pl0100644000175000001450000000550707266422642014735 0ustar iltzuiltzu# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl test.pl' ######################### We start with some black magic to print on failure. # Change 1..1 below to 1..last_test_to_print . # (It may become useful if the test is moved to ./t subdirectory.) BEGIN { $| = 1; print "1..9\n"; } END {print "not ok 1\n" unless $loaded;} use Time::Stopwatch; $loaded = 1; print "ok 1\n"; ######################### End of black magic. # Insert your test code below (better if it prints "ok 13" # (correspondingly "not ok 13") depending on the success of chunk 13 # of the test code): print <<"NOTE" unless Time::Stopwatch::HIRES; ! As Time::HiRes could not be loaded, resolution will be ! ! limited to one second. Some tests will be skipped. ! NOTE # Does the timer work at all? test2: { tie my $timer, 'Time::Stopwatch'; my $start = $timer; sleep(1); my $stop = $timer; print $start < $stop ? "ok" : "not ok", " 2\t# $start < $stop\n"; }; # Can we supply an initial value? test3: { tie my $timer, 'Time::Stopwatch', 32; my $stop = $timer; print $stop >= 32 ? "ok" : "not ok", " 3\t# $stop >= 32\n"; }; # How about assignment? test4: { tie my $timer, 'Time::Stopwatch'; $timer = 64; my $stop = $timer; print $stop >= 64 ? "ok" : "not ok", " 4\t# $stop >= 64\n"; }; # Are fractional times preserved? test5: { tie my $timer, 'Time::Stopwatch', 2.5; my $stop = $timer; print $stop != int($stop) ? "ok" : "not ok", " 5\t# $stop != ${\int($stop)}\n"; }; # Can we do real fractional timing? test6: { print "ok 6\t# skipped, no Time::HiRes\n" and next unless Time::Stopwatch::HIRES; tie my $timer, 'Time::Stopwatch', 1; select(undef,undef,undef,0.25); my $stop = $timer; print $stop != int($stop) ? "ok" : "not ok", " 6\t# $stop != ${\int($stop)}\n"; }; # Is it accurate to one second? test7: { tie my $timer, 'Time::Stopwatch', 2; sleep(2); my $stop = $timer; print int($stop+.5) == 4 ? "ok" : "not ok", " 7\t# 3.5 <= $stop < 4.5\n"; }; # Is it accurate to 1/10 seconds? test8: { print "ok 8\t# skipped, no Time::HiRes\n" and next unless Time::Stopwatch::HIRES; tie my $timer, 'Time::Stopwatch'; select(undef,undef,undef,1.3); my $stop = $timer; print int(10*$stop+.5) == 13 ? "ok" : "not ok", " 8\t# 1.25 <= $stop < 1.35\n"; }; # Does $t++ really make the timer lag? test9: { print "ok 9\t# skipped, no Time::HiRes\n" and next unless Time::Stopwatch::HIRES; tie my $timer, 'Time::Stopwatch'; tie my $delay, 'Time::Stopwatch'; while ($delay < 1) { $timer++; $timer--; } my $stop = $timer; print $stop < 1 ? "ok" : "not ok", " 9\t# $stop < 1 (confirms known bug)\n"; }; __END__ Time-Stopwatch-1.00/README0100644000175000001450000000160507246730520014267 0ustar iltzuiltzu Time::Stopwatch -- version 0.03 The Time::Stopwatch module provides a convenient interface to timing functions through tied scalars. From the point of view of the user, scalars tied to the module simply increase their value by one every second. Installing the Time::HiRes module lets Time::Stopwatch timers provide sub-second accuracy. This feature will be automatically enabled if Time::HiRes is present. To install, just do: perl Makefile.PL make make test make install If Time::HiRes is not installed, some tests will be skipped. Alternatively you may simply put Stopwatch.pm in a subdirectory Time wherever you like to keep your perl modules. Copyright (c) 2000-2001 Ilmari Karonen. All rights reserved. This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Address bug reports and comments to: perl@itz.pp.sci.fi Time-Stopwatch-1.00/MANIFEST0100644000175000001450000000006107246224555014541 0ustar iltzuiltzuStopwatch.pm MANIFEST Makefile.PL test.pl README