[Chapter 7] 7.2.4 Benchmark - Check and Compare Running Times of Code
Author: Larry Wall, Tom Christiansen & Randal L. Schwartz
Date: 1999-07-02T02:01:14Z

#

| Chapter 7 The Standard Perl Library |

### 7.2.4 Benchmark - Check and Compare Running Times of Code

    use Benchmark;

    # timeit():  run $count iterations of the given Perl code, and time it
    $t = timeit($count, 'CODE');  # $t is now a Benchmark object

    # timestr():  convert Benchmark times to printable strings
    print "$count loops of 'CODE' took:", timestr($t), "\n";

    # timediff():  calculate the difference between two times
    $t = timediff($t1 - $t2);

    # timethis():  run "code" $count times with timeit(); also, print out a
    #     header saying "timethis $count: "
    $t = timethis($count, "CODE");

    # timethese():  run timethis() on multiple chunks of code
    @t = timethese($count, {
        'Name1' => '...CODE1...',
        'Name2' => '...CODE2...',
    });

    # new method:  return the current time
    $t0 = new Benchmark;
    # ... your CODE here ...
    $t1 = new Benchmark;
    $td = timediff($t1, $t0);
    print "the code took: ", timestr($td), "\n";

    # debug method:  enable or disable debugging
    Benchmark->debug(1);
    $t = timeit(10, ' 5 ** $Global ');
    Benchmark->debug(0);

The Benchmark module encapsulates a number of routines to help you figure out how long it takes to execute some code a given number of times within a loop.

For the `timeit()` routine, `$count` is the number of times to run the loop. `CODE` is a string containing the code to run. `timeit()` runs a null loop with `$count` iterations, and then runs the same loop with your code inserted. It reports the difference between the times of execution.

For `timethese()`, a loop of `$count` iterations is run on each code chunk separately, and the results are reported separately. The code to run is given as a hash with keys that are names and values that are code. `timethese()` is handy for quick tests to determine which way of doing something is faster. For example:

    $ perl -MBenchmark -Minteger
    timethese(100000, { add => '$i += 2', inc => '$i++; $i++' });
    __END__
    Benchmark: timing 1000000 iterations of add, inc...
           add:  4 secs ( 4.52 usr  0.00 sys =  4.52 cpu)
           inc:  6 secs ( 5.32 usr  0.00 sys =  5.32 cpu)

The following routines are exported into your namespace if you use the Benchmark module:

    timeit()
    timethis()
    timethese()
    timediff()
    timestr()

The following routines will be exported into your namespace if you specifically ask that they be imported:

    clearcache()     # clear just the cache element indexed by $key
    clearallcache()  # clear the entire cache
    disablecache()   # do not use the cache
    enablecache()    # resume caching

#### 7.2.4.1 Notes

Code is executed in the caller's package.

The null loop times are cached, the key being the number of iterations. You can control caching with calls like these:

    clearcache($key);
    clearallcache();
    disablecache();
    enablecache();

Benchmark inherits only from the Exporter class.

The elapsed time is measured using time(2) and the granularity is therefore only one second. Times are given in seconds for the whole loop (not divided by the number of iterations). Short tests may produce negative figures because Perl can appear to take longer to execute the empty loop than a short test.

The user and system CPU time is measured to millisecond accuracy using times(3). In general, you should pay more attention to the CPU time than to elapsed time, especially if other processes are running on the system. Also, elapsed times of five seconds or more are needed for reasonable accuracy.

Because you pass in a string to be evaled instead of a closure to be executed, lexical variables declared with my outside of the eval are not visible.

7.2.3 AutoSplit - Split a Module for Autoloading |  | 7.2.5 Carp - Generate Error Messages