TysonAndre / phan

Phan is a static analyzer for PHP. Phan prefers to avoid false-positives and attempts to prove incorrectness rather than correctness.
Other
0 stars 0 forks source link

Benchmark script results: unserialize takes 2x longer than parse_code, polyfill takes 15x as long #155

Open TysonAndre opened 6 years ago

TysonAndre commented 6 years ago

And igbinary_unserialize is about the same.

This isn't counting the time to read unserialized contents from disk.

It's worth it to cache the polyfill if only the polyfill is available (A full analysis ends up being 2x slower, caching could get this to 1.1x or so)

This may vary slightly in real use cases

<?php
// bench_polyfill_parse took 7.642834
// bench_unserialize took 1.002477
// bench_igbinary_unserialize took 0.410525
// bench_parse took 0.474594

require_once __DIR__ . '/vendor/autoload.php';

use Phan\AST\Parser;
use Phan\AST\ASTSimplifier;
use Phan\Language\Context;
use Phan\CodeBase;

error_reporting(E_ALL);
$contents = file_get_contents(__DIR__ . '/src/Phan/Phan.php');
$old_node = \ast\parse_code($contents, 50);
$node = ASTSimplifier::applyStatic($old_node);
$serialize = serialize($node);
$igbinary_serialize = igbinary_serialize($node);
const ITERATIONS = 1000;

function bench_unserialize(string $serialize, $n = ITERATIONS) {
    $t = microtime(true);
    for ($i = 0; $i < $n; $i++) {
        unserialize($serialize);
    }
    $t2 = microtime(true);
    printf("%s took %.6f\n", __FUNCTION__, $t2-$t);
}

function bench_igbinary_unserialize(string $serialize, $n = ITERATIONS) {
    $t = microtime(true);
    for ($i = 0; $i < $n; $i++) {
        igbinary_unserialize($serialize);
    }
    $t2 = microtime(true);
    printf("%s took %.6f\n", __FUNCTION__, $t2-$t);
}

function bench_parse($contents, $n = ITERATIONS) {
    $t = microtime(true);
    for ($i = 0; $i < $n; $i++) {
        ASTSimplifier::applyStatic(ast\parse_code($contents, 50));
    }
    $t2 = microtime(true);
    printf("%s took %.6f\n", __FUNCTION__, $t2-$t);
}

function bench_polyfill_parse($contents, $n = ITERATIONS) {
    $code_base = require(__DIR__ . '/src/codebase.php');
    $context = new Context();
    $path = 'fake.php';

    $t = microtime(true);
    for ($i = 0; $i < $n; $i++) {
        ASTSimplifier::applyStatic(Parser::parseCodePolyfill($code_base, $context, $path, $contents, false));
    }
    $t2 = microtime(true);
    printf("%s took %.6f\n", __FUNCTION__, $t2-$t);
}

bench_polyfill_parse($contents);
bench_unserialize($serialize);
bench_igbinary_unserialize($igbinary_serialize);
bench_parse($contents);