Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ircmaxell
Last active January 3, 2018 22:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ircmaxell/8859d7f1bbee7b2f6e16 to your computer and use it in GitHub Desktop.
Save ircmaxell/8859d7f1bbee7b2f6e16 to your computer and use it in GitHub Desktop.
bench.php
<?php
use ReckiCT\Jit;
if (function_exists('class_alias')) {
// HippyVM doesn't have a class_alias, so this will break things.
require __DIR__ . '/../vendor/autoload.php';
}
define("IM", 139968);
define("IA", 3877);
define("IC", 29573);
/**
* @return void
*/
function simple()
{
$a = 0;
for ($i = 0; $i < 1000000; $i++)
$a++;
$thisisanotherlongname = 0;
for ($thisisalongname = 0; $thisisalongname < 1000000; $thisisalongname++)
$thisisanotherlongname++;
}
/**
* @engine qb
* @local int $a
* @local int $i
* @local int $thisisanotherlongname
* @local int $thisisalongname
* @return void
*/
function simpleqb()
{
$a = 0;
for ($i = 0; $i < 1000000; $i++)
$a++;
$thisisanotherlongname = 0;
for ($thisisalongname = 0; $thisisalongname < 1000000; $thisisalongname++)
$thisisanotherlongname++;
}
/**
* @return void
*/
function simplecall()
{
for ($i = 0; $i < 1000000; $i++)
strlen("hallo");
}
/**
* @param string $a
* @return void
*/
function hallo($a)
{
}
/**
* @engine qb
* @param string $a
* @return void
*/
function halloqb($a)
{
}
/**
* @return void
*/
function simpleucall()
{
for ($i = 0; $i < 1000000; $i++)
hallo("hallo");
}
/**
* @return void
*/
function simpleudcall()
{
for ($i = 0; $i < 1000000; $i++)
hallo2("hallo");
}
/**
* @engine qb
* @local int $i
* @return void
*/
function simpleucallqb()
{
for ($i = 0; $i < 1000000; $i++)
halloqb("hallo");
}
/**
* @engine qb
* @local int $i
* @return void
*/
function simpleudcallqb()
{
for ($i = 0; $i < 1000000; $i++)
hallo2qb("hallo");
}
/**
* @param string
* @return void
*/
function hallo2($a)
{
}
/**
* @engine qb
* @param string $a
* @return void
*/
function hallo2qb($a)
{
}
/**
* @return void
*/
function mandel()
{
$w1=50;
$h1=150;
$recen=-.45;
$imcen=0.0;
$r=0.7;
$s=0; $rec=0; $imc=0; $re=0; $im=0; $re2=0; $im2=0;
$x=0; $y=0; $w2=0; $h2=0; $color=0;
$s=2*$r/$w1;
$w2=40;
$h2=12;
for ($y=0 ; $y<=$w1; $y=$y+1) {
$imc=$s*($y-$h2)+$imcen;
for ($x=0 ; $x<=$h1; $x=$x+1) {
$rec=$s*($x-$w2)+$recen;
$re=$rec;
$im=$imc;
$color=1000;
$re2=$re*$re;
$im2=$im*$im;
while ( ((($re2+$im2)<1000000) && $color>0)) {
$im=$re*$im*2+$imc;
$re=$re2-$im2+$rec;
$re2=$re*$re;
$im2=$im*$im;
$color=$color-1;
}
if ($color==0) {
// print "_";
} else {
// print "#";
}
}
// print "<br>";
// flush();
}
}
/**
* @return void
*/
function mandel_typed()
{
$w1=50.0;
$h1=150.0;
$recen=-.45;
$imcen=0.0;
$r=0.7;
$s=0.0; $rec=0; $imc=0.0; $re=0.0; $im=0.0; $re2=0.0; $im2=0.0;
$x=0.0; $y=0.0; $w2=0.0; $h2=0.0; $color=0;
$s=2*$r/$w1;
$w2=40.0;
$h2=12.0;
for ($y=0.0 ; $y<=$w1; $y=$y+1.0) {
$imc=$s*($y-$h2)+$imcen;
for ($x=0 ; $x<=$h1; $x=$x+1) {
$rec=$s*($x-$w2)+$recen;
$re=$rec;
$im=$imc;
$color=1000;
$re2=$re*$re;
$im2=$im*$im;
while ( ((($re2+$im2)<1000000.0) && $color>0)) {
$im=$re*$im*2+$imc;
$re=$re2-$im2+$rec;
$re2=$re*$re;
$im2=$im*$im;
$color=$color-1;
}
if ($color==0) {
// print "_";
} else {
// print "#";
}
}
// print "<br>";
// flush();
}
}
/**
* @engine qb
* @local float $w1
* @local float $h1
* @local float $recen
* @local float $imcen
* @local float $r
* @local float $s
* @local float $rec
* @local float $imc
* @local float $re
* @local float $im
* @local float $re2
* @local float $im2
* @local float $x
* @local float $y
* @local float $w2
* @local float $h2
* @local int $color
* @return void
*/
function mandel_typedqb()
{
$w1=50.0;
$h1=150.0;
$recen=-.45;
$imcen=0.0;
$r=0.7;
$s=0.0; $rec=0; $imc=0.0; $re=0.0; $im=0.0; $re2=0.0; $im2=0.0;
$x=0.0; $y=0.0; $w2=0.0; $h2=0.0; $color=0;
$s=2*$r/$w1;
$w2=40.0;
$h2=12.0;
for ($y=0.0 ; $y<=$w1; $y=$y+1.0) {
$imc=$s*($y-$h2)+$imcen;
for ($x=0 ; $x<=$h1; $x=$x+1) {
$rec=$s*($x-$w2)+$recen;
$re=$rec;
$im=$imc;
$color=1000;
$re2=$re*$re;
$im2=$im*$im;
while ( ((($re2+$im2)<1000000.0) && $color>0)) {
$im=$re*$im*2+$imc;
$re=$re2-$im2+$rec;
$re2=$re*$re;
$im2=$im*$im;
$color=$color-1;
}
if ($color==0) {
// print "_";
} else {
// print "#";
}
}
// print "<br>";
// flush();
}
}
/**
* @return void
*/
function mandel2()
{
$b = " .:,;!/>)|&IH%*#";
//float r, i, z, Z, t, c, C;
for ($y=30; /*printf("\n"),*/ $C = $y*0.1 - 1.5, $y--;) {
for ($x=0; $c = $x*0.04 - 2, $z=0, $Z=0, $x++ < 75;) {
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
if ($z*$z + $Z*$Z > 500000) break;
// echo $b[$k%16];
}
}
}
/**
* @return void
*/
function mandel2_typed()
{
$b = " .:,;!/>)|&IH%*#";
//float r, i, z, Z, t, c, C;
for ($y=30; /*printf("\n"),*/ $C = $y*0.1 - 1.5, $y--;) {
for ($x=0; $c = $x*0.04 - 2, $z=0.0, $Z=0.0, $x++ < 75;) {
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
if ($z*$z + $Z*$Z > 500000) break;
// echo $b[$k%16];
}
}
}
/**
* @engine qb
* @local string $b
* @local int $y
* @local float $C
* @local int $x
* @local float $c
* @local float $z
* @local float $Z
* @local float $r
* @local int $k
* @local float $t
* @local float $i
* @return void
*/
function mandel2_typedqb()
{
$b = " .:,;!/>)|&IH%*#";
//float r, i, z, Z, t, c, C;
for ($y=30; /*printf("\n"),*/ $C = $y*0.1 - 1.5, $y--;) {
for ($x=0; $c = $x*0.04 - 2, $z=0.0, $Z=0.0, $x++ < 75;) {
for ($r=$c, $i=$C, $k=0; $t = $z*$z - $Z*$Z + $r, $Z = 2*$z*$Z + $i, $z=$t, $k<5000; $k++)
if ($z*$z + $Z*$Z > 500000) break;
// echo $b[$k%16];
}
}
}
/**
* @param int $m
* @param int $n
* @return int
*/
function Ack($m, $n)
{
if($m == 0) return $n+1;
if($n == 0) return Ack($m-1, 1);
return Ack($m - 1, Ack($m, ($n - 1)));
}
/**
* @engine qb
* @param int $m
* @param int $n
* @return int
*/
function Ackqb($m, $n)
{
if($m == 0) return $n+1;
if($n == 0) return Ackqb($m-1, 1);
return Ackqb($m - 1, Ackqb($m, ($n - 1)));
}
/**
* @param int $n
* @return void
*/
function ackermann($n)
{
$r = Ack(3,$n);
// print "Ack(3,$n): $r\n";
}
/**
* @engine qb
* @param int $n
* @local int $r
* @return void
*/
function ackermannqb($n)
{
$r = Ackqb(3,$n);
// print "Ack(3,$n): $r\n";
}
/**
* @param int $n
* @return void
*/
function ary($n)
{
for ($i=0; $i<$n; $i++) {
$X[$i] = $i;
}
for ($i=$n-1; $i>=0; $i--) {
$Y[$i] = $X[$i];
}
$last = $n-1;
// print "$Y[$last]\n";
}
/**
* @param int $n
* @return void
*/
function ary2($n)
{
for ($i=0; $i<$n;) {
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
$X[$i] = $i; ++$i;
}
for ($i=$n-1; $i>=0;) {
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
$Y[$i] = $X[$i]; --$i;
}
$last = $n-1;
// print "$Y[$last]\n";
}
/**
* @param int $n
* @return void
*/
function ary3($n)
{
for ($i=0; $i<$n; $i++) {
$X[$i] = $i + 1;
$Y[$i] = 0;
}
for ($k=0; $k<1000; $k++) {
for ($i=$n-1; $i>=0; $i--) {
$Y[$i] += $X[$i];
}
}
$last = $n-1;
// print "$Y[0] $Y[$last]\n";
}
/**
* @param int $n
* @return int
*/
function fibo_r($n)
{
return(($n < 2) ? 1 : fibo_r($n - 2) + fibo_r($n - 1));
}
/**
* @param int $n
* @return void
*/
function fibo($n)
{
$r = fibo_r($n);
// print "$r\n";
}
/**
* @param int $n
* @return void
*/
function hash1($n)
{
for ($i = 1; $i <= $n; $i++) {
$X[dechex($i)] = $i;
}
$c = 0;
for ($i = $n; $i > 0; $i--) {
if ($X[dechex($i)]) { $c++; }
}
// print "$c\n";
}
/**
* @param int $n
* @return void
*/
function hash2($n)
{
for ($i = 0; $i < $n; $i++) {
$hash1["foo_$i"] = $i;
$hash2["foo_$i"] = 0;
}
for ($i = $n; $i > 0; $i--) {
foreach($hash1 as $key => $value) $hash2[$key] += $value;
}
$first = "foo_0";
$last = "foo_".($n-1);
// print "$hash1[$first] $hash1[$last] $hash2[$first] $hash2[$last]\n";
}
/**
* @param int $n
* @return int
*/
function gen_random($n)
{
global $LAST;
return( ($n * ($LAST = ($LAST * IA + IC) % IM)) / IM );
}
/**
* @param int $n
* @param int[]
* @return int[]
*/
function heapsort_r($n, $ra)
{
$l = ($n >> 1) + 1;
$ir = $n;
while (1) {
if ($l > 1) {
$rra = $ra[--$l];
} else {
$rra = $ra[$ir];
$ra[$ir] = $ra[1];
if (--$ir == 1) {
$ra[1] = $rra;
return $ra;
}
}
$i = $l;
$j = $l << 1;
while ($j <= $ir) {
if (($j < $ir) && ($ra[$j] < $ra[$j+1])) {
$j++;
}
if ($rra < $ra[$j]) {
$ra[$i] = $ra[$j];
$j += ($i = $j);
} else {
$j = $ir + 1;
}
}
$ra[$i] = $rra;
}
return $ra;
}
/**
* @param int $n
* @return void
*/
function heapsort($N)
{
global $LAST;
$LAST = 42;
for ($i=1; $i<=$N; $i++) {
$ary[$i] = gen_random(1);
}
$ary = heapsort_r($N, $ary);
// printf("%.10f\n", $ary[$N]);
}
/**
* @param int $rows
* @param int $cols
* @return int[][]
*/
function mkmatrix($rows, $cols)
{
$count = 1;
$mx = array();
for ($i=0; $i<$rows; $i++) {
for ($j=0; $j<$cols; $j++) {
$mx[$i][$j] = $count++;
}
}
return($mx);
}
/**
* @param int $rows
* @param int $cols
* @param int[][] $m1
* @param int[][] $m2
* @return int[][]
*/
function mmult($rows, $cols, $m1, $m2)
{
$m3 = array();
for ($i=0; $i<$rows; $i++) {
for ($j=0; $j<$cols; $j++) {
$x = 0;
for ($k=0; $k<$cols; $k++) {
$x += $m1[$i][$k] * $m2[$k][$j];
}
$m3[$i][$j] = $x;
}
}
return($m3);
}
/**
* @param int $n
* @return void
*/
function matrix($n)
{
$SIZE = 30;
$m1 = mkmatrix($SIZE, $SIZE);
$m2 = mkmatrix($SIZE, $SIZE);
while ($n--) {
$mm = mmult($SIZE, $SIZE, $m1, $m2);
}
// print "{$mm[0][0]} {$mm[2][3]} {$mm[3][2]} {$mm[4][4]}\n";
}
/**
* @param int $n
* @return void
*/
function nestedloop($n)
{
$x = 0;
for ($a=0; $a<$n; $a++)
for ($b=0; $b<$n; $b++)
for ($c=0; $c<$n; $c++)
for ($d=0; $d<$n; $d++)
for ($e=0; $e<$n; $e++)
for ($f=0; $f<$n; $f++)
$x++;
// print "$x\n";
}
/**
* @param int $n
* @return void
*/
function sieve($n)
{
$count = 0;
while ($n-- > 0) {
$count = 0;
$flags = range (0,8192);
for ($i=2; $i<8193; $i++) {
if ($flags[$i] > 0) {
for ($k=$i+$i; $k <= 8192; $k+=$i) {
$flags[$k] = 0;
}
$count++;
}
}
}
// print "Count: $count\n";
}
/**
* @param string $n
* @return void
*/
function strcat($n)
{
$str = "";
while ($n-- > 0) {
$str .= "hello\n";
}
$len = strlen($str);
// print "$len\n";
}
/**
* @param int $x
* @param int $y
* @return float
*/
function jumpapaluza($x, $y)
{
$result = 1.0;
for ($i = 0; $i < $x; $i++) {
for ($j = 0; $j < $y; $j++) {
for ($k = 0; $k < $x; $k++) {
for ($m = 0; $m < $y; $m++) {
$result = $result * 1.0001;
}
}
}
}
return $result;
}
/**
* @param int $x
* @return int
*/
function bitapaluza1($x)
{
$a = 1;
$b = 1 << 63;
$c = 0;
$d = 0;
$e = 0;
$f = 0;
for ($i = 0; $i < (1 << $x); $i++) {
$a <<= 1;
$b >>= 1;
$c = $a | $b;
$d = $a ^ $b;
$e = $a & $b;
$f = ~$a;
while ($a >>= 1) {
$c = $d << $e;
$d = $e >> $f;
$e = $f << $c;
$f = $c >> $d;
}
}
return $a + $b + $c + $d;
}
/**
* @param int $x
* @return int
*/
function bitapaluza2($x)
{
$a = 1;
$b = 1 << 63;
$c = 0;
$d = 0;
$e = 0;
$f = 0;
for ($i = 0; $i < (1 << $x); $i++) {
$a <<= 1;
$b >>= 1;
$c = $a | $b;
$d = $a ^ $b;
$e = $a & $b;
$f = ~$a;
$l = 1 << 8;
while ($l >>= 1) {
$c = $d << $e;
$d = $e >> $f;
$e = $f << $c;
$f = $c >> $d;
}
}
return $a + $b + $c + $d;
}
$tests = array(
"simple" => array(),
"simplecall" => array(),
"simpleucall" => array(),
"simpleudcall" => array(),
"mandel" => array(),
"mandel_typed" => array(),
"mandel2" => array(),
"mandel2_typed" => array(),
"ackermann" => array(7),
"ary" => array(50000),
"ary2" => array(50000),
"ary3" => array(2000),
"fibo" => array(30),
"hash1" => array(50000),
"hash2" => array(500),
"heapsort" => array(20000),
"matrix" => array(20),
"nestedloop" => array(12),
"sieve" => array(30),
"strcat" => array(200000),
"jumpapaluza" => array(50, 50),
"bitapaluza1" => array(21),
"bitapaluza2" => array(18),
);
if (isset($argv[1]) && isset($tests[$argv[1]])) {
print executeTest($argv[1], $tests[$argv[1]], isset($argv[2]) ? $argv[2] : '');
die();
}
$environments = array("php");
if (extension_loaded('jitfu')) {
$environments[] = 'jit';
}
$hhvmVersion = 0;
@exec("hhvm --version", $output);
if (isset($output[0]) && strpos($output[0], "HipHop") !== false) {
$environments[] = "hhvm";
if (preg_match('(\d\.\d\.\d)', $output[0], $match)) {
$hhvmVersion = $match;
}
}
$output = [];
@exec("hippy-c --version", $output);
if (isset($output[0]) && strpos($output[0], "Hippy VM") !== false) {
$environments[] = "hippy-c";
}
if (extension_loaded('qb')) {
$environments[] = 'qb';
}
$result = array();
foreach ($tests as $test => $args) {
$id = $test . "(" . implode(", ", $args) . ")";
echo $id . "\n";
foreach ($environments as $environment) {
$results[$id][$environment] = executeTest($test, $args, $environment);
$name = "$id - $environment:";
echo $name . str_repeat(" ", 30 - strlen($name));
echo " {$results[$id][$environment]}\n";
}
}
$cells = array(0 => [''], 1 => ['-']);
foreach ($environments as $env) {
$cells[1][] = '-';
switch ($env) {
case 'php':
$cells[0][] = 'PHP ' . PHP_VERSION;
break;
case 'jit':
$cells[0][] = 'ReckiCT';
break;
case 'hhvm':
$cells[0][] = "HHVM - $hhvmVersion";
break;
case 'hippy-c':
$cells[0][] = "HippyVM - master";
break;
case 'qb':
$cells[0][] = "PHP-QB 2.4";
break;
default:
$cells[0][] = $env;
}
}
foreach ($results as $test => $envs) {
$row = [$test];
$score = min($envs);
foreach ($envs as $env => $res) {
if (!is_infinite($res)) {
$res = $res / $score;
if ($res === 1.0) {
$row[] = '**1.00000**';
} else {
$row[] = sprintf("%10.5f", $res);
}
} else {
$row[] = 'FAIL';
}
}
$cells[] = $row;
}
$columnPaddings = array_fill(0, count($cells[0]), 0);
foreach ($cells as $row) {
foreach ($row as $key => $col) {
$columnPaddings[$key] = max($columnPaddings[$key], strlen($col) + 1);
}
}
echo "Results:\n";
foreach ($cells as $row) {
$colSep = '';
foreach ($row as $key => $col) {
$padStr = ' ';
if ($col === '-') {
$padStr = '-';
}
echo $colSep . $padStr . str_pad($col, $columnPaddings[$key], $padStr);
$colSep = '|';
}
echo "\n";
}
function executeTest(callable $test, array $args, $environment = '')
{
switch ($environment) {
case 'hhvm':
$result = (float) @exec('hhvm ' . __FILE__ . " $test");
if ($result === 0.0) {
$result = INF;
}
return $result;
case 'hippy-c':
$result = (float) @exec('hippy-c ' . __FILE__ . " $test");
if ($result === 0.0) {
$result = INF;
}
return $result;
case 'dump':
Jit::JitFu($test)->dump("func");
case 'dumpimage':
$graph = Jit::getInstance()->getFunctionGraph($test);
(new ReckiCT\Util\GraphPrinter)->generateImage($graph->getGraph(), 'graph.png', 'png');
return;
case 'dumpc':
$test = Jit::JitFu($test);
$test->compile();
$test->dump("func");
return;
case 'dumpir':
$ir = Jit::getInstance()->getFunctionIr($test);
echo $ir . "\n";
return;
case 'jitprint':
$test = Jit::JitFu($test);
case 'print':
var_dump(call_user_func_array($test, $args));
return;
case 'qb':
if (function_exists($test . 'qb')) {
$test = $test . 'qb';
} else {
return INF;
}
break;
case 'jit':
try {
$test = Jit::JitFu($test);
} catch (\Exception $e) {
return INF;
}
break;
}
$runs = [];
for ($i = 0; $i < 5; $i++) {
ob_start();
$start = microtime(true);
call_user_func_array($test, $args);
$end = microtime(true);
$runs[] = $end - $start;
ob_end_clean();
}
// remove the slowest two runs
unset($runs[array_search(min($runs), $runs)]);
unset($runs[array_search(min($runs), $runs)]);
return array_sum($runs) / count($runs);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment