Benchmarks for the comparison of various styles of writing a clamp
function in PHP
<?php
namespace Potherca\Example;
/**
* Benchmark the separate `clamp` functions.
*/
class BenchmarkClamp
{
/**
* @ParamProviders({"provideValues"})
*/
public function bench_7BC1F85B($value, $min, $max)
{
if ($value < $min) {
$value = $min;
}
if ($value > $max) {
$value = $max;
}
return $value;
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_83C742FF($value, $min, $max)
{
if ($value < $min) {
return $min;
}
if ($value > $max) {
return $max;
}
return $value;
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_832B9C44($value, $min, $max)
{
return min($max, max($min, $value));
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_8389C469($value, $min, $max)
{
if ($value < $min) {
$value = $min;
} elseif ($value > $max) {
$value = $max;
}
return $value;
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_CAB599E9($value, $min, $max)
{
if ($value < $min) {
return $min;
} elseif ($value > $max) {
return $max;
} else {
return $value;
}
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_60AA891E($value, $min, $max)
{
return $value < $min ? $min : ( $value > $max ? $max : $value );
}
/**
* @ParamProviders({"provideValues"})
*/
public function bench_A13E087E($value, $min, $max)
{
if ($value < $min) return $min;
if ($value > $max) return $max;
return $value;
}
/**
* Provides data for 3 separate scenario's
*
* @return array
*/
public function provideValues()
{
return [
'above range' => [30, 10, 20],
'beneath range' => [10, 20, 30],
'within range' => [20, 10, 30],
];
}
}
/*EOF*/
ð This text is part of the article Comparison of various styles of writing a clamp
function in PHP
Benchmarks were created using PhpBench counting in units of Ξs
(1).
The final result was:
mean | subject | description |
---|---|---|
20.035 Ξs | 832B9C44 | return min max |
23.376 Ξs | CAB599E9 | if/return, elseif/return, else/return |
23.538 Ξs | A13E087E | if/return, if/return, return (shorthand) |
23.595 Ξs | 8389C469 | if, elseif, return |
23.723 Ξs | 60AA891E | return/ternary/ternary |
23.985 Ξs | 83C742FF | if/return, if/return, return |
24.089 Ξs | 7BC1F85B | if, if, return; |
The following steps were taken in order to benchmark the clamp
variations:
phpbench
Each step is described in detail below.
I create a class that held a separate method for each variation. Each variation was fed data for 3 separate scenario's:
The source code can be seen in the BenchmarkClamp.php
file.
phpbench
PhpBench was run using the following command:
phpbench run ./BenchmarkClamp.php --iterations=15 --revs=1000 --retry-threshold=5 --report='generator: "table", cols: [ "subject", "params", "mean", "diff" ], break: ["benchmark"], sort: {subject: "asc", mean: "desc"}'
This gives the following results:
7 subjects, 315 iterations, 21,000 revs, 0 rejects
(best [mean mode] worst) = 19.098 [23.192 23.167] 20.588 (Ξs)
â
T: 7,305.424Ξs ΞSD/r 0.408Ξs ΞRSD/r: 1.761%
benchmark: BenchmarkClamp
+----------------+------------+----------+---------+
| subject | params | mean | diff |
+----------------+------------+----------+---------+
| bench_60AA891E | [20,10,30] | 23.944Ξs | +19.98% |
| bench_60AA891E | [30,10,20] | 23.657Ξs | +18.54% |
| bench_60AA891E | [10,20,30] | 23.569Ξs | +18.10% |
| bench_7BC1F85B | [30,10,20] | 24.395Ξs | +22.24% |
| bench_7BC1F85B | [20,10,30] | 24.335Ξs | +21.94% |
| bench_7BC1F85B | [10,20,30] | 23.538Ξs | +17.95% |
| bench_832B9C44 | [30,10,20] | 20.188Ξs | +1.16% |
| bench_832B9C44 | [10,20,30] | 19.961Ξs | +0.02% |
| bench_832B9C44 | [20,10,30] | 19.957Ξs | 0.00% |
| bench_8389C469 | [30,10,20] | 23.668Ξs | +18.60% |
| bench_8389C469 | [20,10,30] | 23.581Ξs | +18.16% |
| bench_8389C469 | [10,20,30] | 23.537Ξs | +17.94% |
| bench_83C742FF | [10,20,30] | 24.324Ξs | +21.89% |
| bench_83C742FF | [20,10,30] | 23.890Ξs | +19.71% |
| bench_83C742FF | [30,10,20] | 23.742Ξs | +18.97% |
| bench_A13E087E | [10,20,30] | 23.752Ξs | +19.02% |
| bench_A13E087E | [30,10,20] | 23.513Ξs | +17.82% |
| bench_A13E087E | [20,10,30] | 23.349Ξs | +17.00% |
| bench_CAB599E9 | [20,10,30] | 23.678Ξs | +18.65% |
| bench_CAB599E9 | [30,10,20] | 23.317Ξs | +16.84% |
| bench_CAB599E9 | [10,20,30] | 23.135Ξs | +15.93% |
+----------------+------------+----------+---------+
Combining the result-sets for the 3 separate scenario's, we get:
subject | mean | |
---|---|---|
832B9C44 | (20.188 + 19.961 + 19.957)/3 = | 20.0353333 |
CAB599E9 | (23.678 + 23.317 + 23.135)/3 = | 23.3766667 |
A13E087E | (23.752 + 23.513 + 23.349)/3 = | 23.5380000 |
8389C469 | (23.668 + 23.581 + 23.537)/3 = | 23.5953333 |
60AA891E | (23.944 + 23.657 + 23.569)/3 = | 23.7233333 |
83C742FF | (24.324 + 23.890 + 23.742)/3 = | 23.9853333 |
7BC1F85B | (24.395 + 24.335 + 23.538)/3 = | 24.0893333 |
Translating this back to each variation this gives us:
mean | subject | description |
---|---|---|
20.0353333 Ξs | 832B9C44 | return min max |
23.3766667 Ξs | CAB599E9 | if/return, elseif/return, else/return |
23.5380000 Ξs | A13E087E | if/return, if/return, return (shorthand) |
23.5953333 Ξs | 8389C469 | if, elseif, return |
23.7233333 Ξs | 60AA891E | return/ternary/ternary |
23.9853333 Ξs | 83C742FF | if/return, if/return, return |
24.0893333 Ξs | 7BC1F85B | if, if, return; |
Footnotes