Skip to content

Instantly share code, notes, and snippets.

@nikic
Created October 10, 2015 16:25
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 nikic/e98c0057127405791b64 to your computer and use it in GitHub Desktop.
Save nikic/e98c0057127405791b64 to your computer and use it in GitHub Desktop.
<?php error_reporting(E_ALL);
function formatT($t) {
return sprintf('%.1f mus', $t * 1000000);
}
function formatResult($result) {
list($mean, $stddev) = $result;
return formatT($mean) . " +/- " . formatT($stddev);
}
function median($dts) {
$numRuns = count($dts);
sort($dts);
if ($numRuns % 2 == 0) {
return $dts[$numRuns / 2];
} else {
return ($dts[($numRuns - 1) / 2] + $dts[($numRuns + 1) / 2]) / 2;
}
}
function stddev($dts, $mean) {
$sum = 0;
foreach ($dts as $dt) {
$sum += ($dt - $mean) * ($dt - $mean);
}
return sqrt($sum / (count($dts) - 1));
}
function nameWidth($names) {
$lens = array_map('strlen', $names);
$maxLen = max($lens);
return $maxLen;
}
function runTest(callable $test) {
$targetRuntime = 0.3;
$maxFactor = 10;
$numRuns = 6;
// Find appropriate $n to run for $targetTime
$n = 50;
while (true) {
$t = microtime(true);
$test($n);
$dt = microtime(true) - $t;
if ($dt >= $targetRuntime * 0.9) {
break;
}
$newN = $n * $targetRuntime / $dt;
$n = $newN < $maxFactor * $n ? $newN : $maxFactor * $n;
}
$dts = [];
for ($i = 0; $i < $numRuns; ++$i) {
$t = microtime(true);
$test($n);
$dts[] = microtime(true) - $t;
}
$mean = array_sum($dts) / count($dts);
$stddev = stddev($dts, $mean);
$mean /= $n;
$stddev /= $n;
//$median = median($dts);
//$median /= $n;
return [$mean, $stddev];
}
function runTests(array $tests) {
$opts = getopt('', ['save:', 'against:']);
$baseline = null;
if (isset($opts['against'])) {
$file = $opts['against'];
if (!file_exists($file)) {
die("File $file does not exist\n");
}
$baseline = json_decode(file_get_contents($file), true);
}
$nameWidth = nameWidth(array_keys($tests));
$results = [];
foreach ($tests as $name => $test) {
echo str_pad($name . ": ", $nameWidth + 2);
$results[$name] = runTest($test);
echo formatResult($results[$name]);
if (null !== $baseline) {
echo " ", formatResult($baseline[$name]);
$mean = $results[$name][0];
$baseMean = $baseline[$name][0];
$change = ($mean - $baseMean) / $baseMean * 100;
echo " ", sprintf("%+6.1f", $change), "%";
}
echo "\n";
}
if (isset($opts['save'])) {
file_put_contents($opts['save'], json_encode($results));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment