|  | 
|  | 1 | +<?php | 
|  | 2 | + | 
|  | 3 | +require_once __DIR__ . '/shared.php'; | 
|  | 4 | + | 
|  | 5 | +$commitResult = ($argv[1] ?? 'false') === 'true'; | 
|  | 6 | +$phpCgi = $argv[2] ?? dirname(PHP_BINARY) . '/php-cgi'; | 
|  | 7 | +if (!file_exists($phpCgi)) { | 
|  | 8 | +    fwrite(STDERR, "php-cgi not found\n"); | 
|  | 9 | +    exit(1); | 
|  | 10 | +} | 
|  | 11 | + | 
|  | 12 | +function main() { | 
|  | 13 | +    global $commitResult; | 
|  | 14 | + | 
|  | 15 | +    $data = []; | 
|  | 16 | +    $data['bench.php'] = runBench(); | 
|  | 17 | +    $data['symfony_demo'] = runSymfonyDemo(); | 
|  | 18 | +    $data['wordpress_6.2'] = runWordpress(); | 
|  | 19 | +    $result = json_encode($data, JSON_PRETTY_PRINT) . "\n"; | 
|  | 20 | + | 
|  | 21 | +    if ($commitResult) { | 
|  | 22 | +        commitResult($result); | 
|  | 23 | +    } else { | 
|  | 24 | +        fwrite(STDOUT, $result); | 
|  | 25 | +    } | 
|  | 26 | +} | 
|  | 27 | + | 
|  | 28 | +function commitResult(string $result) { | 
|  | 29 | +    $repo = __DIR__ . '/repos/data'; | 
|  | 30 | +    cloneRepo($repo, 'git@github.com:iluuu1994/php-benchmark-data.git'); | 
|  | 31 | +    runCommand(['git', 'pull', '--end-of-options', 'origin'], $repo); | 
|  | 32 | + | 
|  | 33 | +    $commitHash = getPhpSrcCommitHash(); | 
|  | 34 | +    $dir = $repo . '/' . substr($commitHash, 0, 2) . '/' . $commitHash; | 
|  | 35 | +    $summaryFile = $dir . '/summary.json'; | 
|  | 36 | +    if (!is_dir($dir)) { | 
|  | 37 | +        mkdir($dir, 0755, true); | 
|  | 38 | +    } | 
|  | 39 | +    file_put_contents($summaryFile, $result); | 
|  | 40 | + | 
|  | 41 | +    runCommand(['git', 'add', '--end-of-options', $summaryFile], $repo); | 
|  | 42 | +    runCommand(['git', 'commit', '--allow-empty', '-m', 'Add result for php/php-src@' . $commitHash, '--author', 'Benchmark <benchmark@php.net>'], $repo); | 
|  | 43 | +    runCommand(['git', 'push'], $repo); | 
|  | 44 | +} | 
|  | 45 | + | 
|  | 46 | +function getPhpSrcCommitHash(): string { | 
|  | 47 | +    $result = runCommand(['git', 'log', '--pretty=format:%H', '-n', '1'], dirname(__DIR__)); | 
|  | 48 | +    return $result->stdout; | 
|  | 49 | +} | 
|  | 50 | + | 
|  | 51 | +function runBench(): array { | 
|  | 52 | +    $process = runValgrindPhpCgiCommand([dirname(__DIR__) . '/Zend/bench.php']); | 
|  | 53 | +    return ['instructions' => extractInstructionsFromValgrindOutput($process->stderr)]; | 
|  | 54 | +} | 
|  | 55 | + | 
|  | 56 | +function runSymfonyDemo(): array { | 
|  | 57 | +    $dir = __DIR__ . '/repos/symfony-demo-2.2.3'; | 
|  | 58 | +    cloneRepo($dir, 'git@github.com:iluuu1994/symfony-demo-2.2.3.git'); | 
|  | 59 | +    runPhpCommand([$dir . '/bin/console', 'cache:clear']); | 
|  | 60 | +    runPhpCommand([$dir . '/bin/console', 'cache:warmup']); | 
|  | 61 | +    $process = runValgrindPhpCgiCommand(['-T1,1', $dir . '/public/index.php']); | 
|  | 62 | +    return ['instructions' => extractInstructionsFromValgrindOutput($process->stderr)]; | 
|  | 63 | +} | 
|  | 64 | + | 
|  | 65 | +function runWordpress(): array { | 
|  | 66 | +    $dir = __DIR__ . '/repos/wordpress-6.2'; | 
|  | 67 | +    cloneRepo($dir, 'git@github.com:iluuu1994/wordpress-6.2.git'); | 
|  | 68 | + | 
|  | 69 | +    /* FIXME: It might be better to use a stable version of PHP for this command because we can't | 
|  | 70 | +     * easily alter the phar file */ | 
|  | 71 | +    runPhpCommand([ | 
|  | 72 | +        '-d error_reporting=0', | 
|  | 73 | +        'wp-cli.phar',  | 
|  | 74 | +        'core', | 
|  | 75 | +        'install', | 
|  | 76 | +        '--url=wordpress.local', | 
|  | 77 | +        '--title="Wordpress"', | 
|  | 78 | +        '--admin_user=wordpress', | 
|  | 79 | +        '--admin_password=wordpress', | 
|  | 80 | +        '--admin_email=benchmark@php.net', | 
|  | 81 | +    ], $dir); | 
|  | 82 | + | 
|  | 83 | +    // Warmup | 
|  | 84 | +    runPhpCommand([$dir . '/index.php'], $dir); | 
|  | 85 | +    $process = runValgrindPhpCgiCommand(['-T1,1', $dir . '/index.php'], $dir); | 
|  | 86 | +    return ['instructions' => extractInstructionsFromValgrindOutput($process->stderr)]; | 
|  | 87 | +} | 
|  | 88 | + | 
|  | 89 | +function runPhpCommand(array $args, ?string $cwd = null): ProcessResult { | 
|  | 90 | +    return runCommand([PHP_BINARY, ...$args], $cwd); | 
|  | 91 | +} | 
|  | 92 | + | 
|  | 93 | +function runValgrindPhpCgiCommand(array $args, ?string $cwd = null): ProcessResult { | 
|  | 94 | +    global $phpCgi; | 
|  | 95 | +    return runCommand([ | 
|  | 96 | +        'valgrind', | 
|  | 97 | +        '--tool=callgrind', | 
|  | 98 | +        '--dump-instr=yes', | 
|  | 99 | +        '--callgrind-out-file=/dev/null', | 
|  | 100 | +        '--', | 
|  | 101 | +        $phpCgi, | 
|  | 102 | +        '-d max_execution_time=0', | 
|  | 103 | +        ...$args, | 
|  | 104 | +    ]); | 
|  | 105 | +} | 
|  | 106 | + | 
|  | 107 | +function extractInstructionsFromValgrindOutput(string $output): ?string { | 
|  | 108 | +    preg_match("(==[0-9]+== Events    : Ir\n==[0-9]+== Collected : (?<instructions>[0-9]+))", $output, $matches); | 
|  | 109 | +    return $matches['instructions'] ?? null; | 
|  | 110 | +} | 
|  | 111 | + | 
|  | 112 | +main(); | 
0 commit comments