Config Linters

Configuration Linters

HTML Output

One approach for comparing classes which implement the same interface is to create an abstract BenchCase class which sets up the fixtures and delegates to a child class to create the concerete instance of the class we want to test:

use Generator;
use PhpBench\Config\ConfigLinter;


/**
 * @Groups("config_linters")
 */
abstract class LinterBenchCase
{
    /**
     * @var ConfigLinter
     */
    private $linter;

    /**
     * @var string
     */
    private $json = '';

    public function __construct()
    {
        $this->linter = $this->createLinter();
    }

    public abstract function createLinter(): ConfigLinter;

    /**
     * @ParamProviders({"provideScale"})
     * @BeforeMethods({"setUpJsonString"})
     */
    public function benchLint(): void
    {
        $this->linter->lint('path/to.json', $this->json);
    }

    public function setUpJsonString(array $params): void
    {
        $data = self::buildData($params[0]);
        $this->json = json_encode($data, JSON_PRETTY_PRINT);
    }

    public function provideScale(): Generator
    {
        yield [1];
        yield [2];
        yield [3];
    }

    public static function buildData(int $size): array
    {
        $data = [];
        for ($i = 0; $i < $size; $i++) {
            if ($size - 1 === 0) {
                $data['key-' . $i] = 'test';
                break;
            }
            $data['key-' . $i] = self::buildData($size - 1);
        }

        return $data;
    }
}

The concrete benchmarks will look like:

use PhpBench\Config\ConfigLinter;
use PhpBench\Config\Linter\SeldLinter;
use PhpBench\Examples\Benchmark\ConfigLinters\LinterBenchCase;

class SeldLinterBench extends LinterBenchCase
{
    public function createLinter(): ConfigLinter
    {
        return new SeldLinter();
    }
}

The report can use the @Groups defined in the abstract class to compare these benchmarks:

{
    "report.generators": {
        "config_linters": {
            "title": "Linter comparison",
            "description": "Compares different implementations of the PHPBench config linter",
            "generator": "component",
            "filter": "contains(subject_groups, 'config_linters')",
            "components": [
                {
                    "component": "bar_chart_aggregate",
                    "x_partition": "'JSON Scale ' ~ variant_params[0]",
                    "bar_partition": "benchmark_name",
                    "y_expr": "mode(partition['result_time_avg']) as time",
                    "y_axes_label": "yValue as time"
                },
                {
                    "component": "section",
                    "tabbed": true,
                    "partition": ["benchmark_name"],
                    "components": [
                        {
                            "title": "{{ first(frame['benchmark_name']) }}",
                            "component": "table_aggregate",
                            "partition": ["variant_name"],
                            "row": {
                                "variant": "'JSON Scale ' ~ first(partition['variant_params'][0])",
                                "memory": "first(partition['result_mem_peak']) as memory",
                                "min": "min(partition['result_time_avg']) as time",
                                "max": "max(partition['result_time_avg']) as time",
                                "mode": "mode(partition['result_time_avg']) as time",
                                "rstdev": "rstdev(partition['result_time_avg'])",
                                "stdev": "stdev(partition['result_time_avg']) as time"
                            }
                        }
                    ]
                }
            ]
        }
    }
}