Skip to content

Instantly share code, notes, and snippets.

@mindplay-dk
Created July 19, 2014 09:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mindplay-dk/743d3ea3521dc4105d7e to your computer and use it in GitHub Desktop.
Save mindplay-dk/743d3ea3521dc4105d7e to your computer and use it in GitHub Desktop.
Cut-and-paste benchmarking library with baseline compensation and weighted averages
<?php
header('Content-type: text/plain');
define('NUM_RUNS', 200); // total number of runs/readings
define('NUM_LOOP', 100); // number of iterations per run
// benchmark a function using various PHP features to establish
// a performance baseline for the PHP version / platform / etc.:
$baseline = bench(function() {
$n = 12345.12345;
$s = str_repeat('0123456789', 10);
$s1 = substr($s, 0, 20);
$s2 = substr($s, 10, 40) . $s1;
$s3 = substr($s, 20, 20) . $s2;
$s4 = substr($s3, 20, 40);
$n1 = floor($n);
$n2 = round($n);
$n3 = sin($n);
$n4 = cos($n);
$a = array('foo'=>100, 'bar'=>200, 'baz'=>300);
$e = '{"foo":100,"bar":200,"baz":300}';
$j = json_encode($a);
$d = json_decode($e, true);
if ($a !== $d) die('internal error (1)');
if ($e !== $j) die('internal error (2)');
$a1 = $a['foo'];
$a2 = $a['bar'];
$a3 = $a['baz'];
$x1 = parse_url('scheme://domain:port/path?query_string#fragment_id');
$x2 = preg_match('/(?P<name>\w+): (?P<digit>\d+)/', 'foobar: 2008', $matches);
$x3 = date('Y-m-d H:i:s', strtotime('2014-02-13 09:36:27'));
$x4 = sha1('abcdefghijklmnopqrstuvwxyz', $x3);
});
echo "BASELINE = " . number_format(1000*$baseline, 3) . " msec\n";
echo PHP_OS . "\n";
echo PHP_VERSION . "\n";
echo NUM_RUNS . " test runs\n\n";
function bench($func) {
$time = array();
for ($i=0; $i<=NUM_RUNS; $i++) {
$start = microtime(true);
for ($n=0; $n<NUM_LOOP; $n++) {
$func();
}
$end = microtime(true);
$time[$i] = ($end - $start) * 1000 / NUM_LOOP;
}
unset($time[0]); // ignore the first reading (usually inaccurate)
return weighted_average($time);
}
function mark($text, $func) {
$time = bench($func);
echo "* " . str_pad($text . ' ', 40, '.')
. str_pad(' ' . number_format(($time*1000), 3) . ' msec ', 20, '.', STR_PAD_LEFT)
. str_pad(' ' . number_format(($time*1000/$GLOBALS['baseline']), 3) . ' points', 20, '.', STR_PAD_LEFT) . "\n";
}
function weighted_average($values) {
$sum = 0;
foreach ($values as $i => $value) {
$sum += $value;
}
$avg = $sum / count($values);
$error = array();
$max_error = 0;
foreach ($values as $i => $value) {
$error[$i] = abs($avg - $value);
$max_error = max($error[$i], $max_error);
}
$total_weight = 0;
$weighted_sum = 0;
foreach ($values as $i => $value) {
$weight = 1 - ($error[$i] / $max_error);
$weight = $weight * $weight; // square
$total_weight += $weight;
$weighted_sum += $weight * $value;
}
$weighted_average = $weighted_sum / $total_weight;
return $weighted_average;
}
// Now benchmark your functions like this:
mark(
'Building a string',
function () {
$foo = 'foo';
$foo .= 'bar';
$foo .= 'baz';
}
);
@mindplay-dk
Copy link
Author

Packaged version here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment