Created
July 13, 2017 07:46
-
-
Save prolic/17df6b38656b50aa990fa4adaf858b99 to your computer and use it in GitHub Desktop.
functional programming benchmarks in PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace f; | |
use ReflectionFunction; | |
const curry = 'f\curry'; | |
function curry(callable $f, ...$args) | |
{ | |
return function (...$partialArgs) use ($f, $args) { | |
return (function ($args) use ($f) { | |
return count($args) < (new ReflectionFunction($f))->getNumberOfRequiredParameters() | |
? curry($f, ...$args) | |
: $f(...$args); | |
})(array_merge($args, $partialArgs)); | |
}; | |
} | |
function printTime(string $r, float $t, float $l) { | |
echo $r . PHP_EOL; | |
$e = $t - $l; | |
echo 'time: ' . ($t) . 's (without loop: ' . $e . 's, per 100 executions ' . ($e / 100) . 's)' . PHP_EOL . PHP_EOL; | |
} | |
function executeLoop(callable $f, ...$args): float { | |
$s = microtime(true); | |
for ($i = 0; $i < 1000000; $i++) { | |
echo $f(...$args); | |
} | |
$t = microtime(true) - $s; | |
return $t; | |
} | |
$simpleCall = function ($x) { | |
return $x + 1; | |
}; | |
$wrappedCall = function ($x) { | |
return function () use ($x) { | |
return $x + 1; | |
}; | |
}; | |
$doubleWrappedCall = function ($x) { | |
return function () use ($x) { | |
return function () use ($x) { | |
return $x + 1; | |
}; | |
}; | |
}; | |
$manyArgs = function ($x, $y, $z) { | |
return $x + $y + $z; | |
}; | |
$manyArgsToOne = function ($x) { | |
return function ($y) use ($x) { | |
return function ($z) use ($x, $y) { | |
return $x + $y + $z; | |
}; | |
}; | |
}; | |
$curried = curry(function ($x, $y, $z) { | |
return $x + $y + $z; | |
}); | |
$l = executeLoop(function () {}); | |
echo 'loop time: ' . $l . 's' . PHP_EOL . PHP_EOL; | |
$t = executeLoop(function ($x) use ($simpleCall) { | |
$simpleCall($x); | |
}, 1); | |
printTime('simpleCall', $t, $l); | |
$t = executeLoop(function ($x) use ($wrappedCall) { | |
$wrappedCall($x)(); | |
}, 1); | |
printTime('wrappedCall', $t, $l); | |
$t = executeLoop(function ($x) use ($doubleWrappedCall) { | |
$doubleWrappedCall($x)()(); | |
}, 1); | |
printTime('doubleWrappedCall', $t, $l); | |
$t = executeLoop(function ($x, $y, $z) use ($manyArgs) { | |
$manyArgs($x, $y, $z); | |
}, 1, 1, 1); | |
printTime('manyArgs', $t, $l); | |
$t = executeLoop(function ($x, $y, $z) use ($manyArgsToOne) { | |
$manyArgsToOne($x)($y)($z); | |
}, 1, 1, 1); | |
printTime('manyArgsToOne', $t, $l); | |
$t = executeLoop(function ($x, $y, $z) use ($curried) { | |
$curried($x)($y)($z); | |
}, 1, 1, 1); | |
printTime('curried', $t, $l); | |
// output: | |
loop time: 0.05836009979248s | |
simpleCall | |
time: 0.11742186546326s (without loop: 0.059061765670776s, per 100 executions 0.00059061765670776s) | |
wrappedCall | |
time: 0.44442796707153s (without loop: 0.38606786727905s, per 100 executions 0.0038606786727905s) | |
doubleWrappedCall | |
time: 0.72968101501465s (without loop: 0.67132091522217s, per 100 executions 0.0067132091522217s) | |
manyArgs | |
time: 0.15100598335266s (without loop: 0.092645883560181s, per 100 executions 0.00092645883560181s) | |
manyArgsToOne | |
time: 0.73799300193787s (without loop: 0.67963290214539s, per 100 executions 0.0067963290214539s) | |
curried | |
time: 3.7121551036835s (without loop: 3.653795003891s, per 100 executions 0.03653795003891s) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment