Greenlight

Documentation

Evidence

On this page

Benchmarks

The benchmark compares complete command run times for generated test suites. It does not measure test-body time in isolation.

Save all samples from the full comparison:

php tools/benchmark.php --with-comparisons --format=json > benchmark.json

To keep the table and save the same run as JSON, use --output:

php tools/benchmark.php --with-comparisons --output=benchmark.json

Select a new output path for each run. The harness refuses to replace a file. It creates the file before the benchmark to check write access. The file stays empty until the harness writes the final report.

Run a Greenlight-only benchmark with the default table report:

php tools/benchmark.php

The coverage-heavy benchmark shape requires PCOV or Xdebug.

Measurement controls

The harness applies these controls before and during each measurement:

The timer includes process start, autoload, discovery, report creation, and execution. It measures the complete command that a user runs.

Output modes are not identical because the tools have different reporter interfaces. Each tool creates its default noninteractive output. Greenlight selects its plain reporter explicitly. The harness discards all output.

Each comparison configuration has a separate cache directory. One tool cannot warm or change the cache of another tool.

Use the JSON report to inspect each exact command.

These controls use the default options. Custom run counts can produce an unbalanced sample order. The report warns when configuration positions have different sample counts. A multiple of twice the configuration count gives equal position counts. The report also warns about fewer than twelve samples or no warmups. Verification still runs when the warmup count is zero.

Comparison tools

Use --with-comparisons to add these pinned tools:

The harness installs the tools in each temporary project. Pest uses its closure-style test syntax. The Pest comparison includes serial and parallel configurations.

The comparison tools run only the six common benchmark shapes. The other shapes use Greenlight features that do not have equivalent configurations.

The common benchmark shapes are:

The Greenlight-specific benchmark shapes are:

The minimal result includes discovery, reports, and one test. It does not measure process startup alone. Do not subtract it from another shape as an exact estimate of test execution time.

The few-slow shape measures concurrent waits. It does not establish CPU scaling. Use cpu-bound to examine fixed CPU work without sleeps. At scale 10, that shape has 40 classes and 80 tests. All three fixture formats use the same arithmetic loop and verify the same result. Scale changes the number of classes, not the work per test.

Execution modes

The report identifies the execution mode for each configuration:

Greenlight with one worker uses the in-process adapter. It does not provide process isolation. The many-isolated report warns that its one-worker result is not an equivalent isolation baseline. Keep this distinction in performance claims. Other specialized shapes can also exercise different adapter paths.

With --workers=1, the harness measures the Greenlight in-process configuration once. ParaTest and parallel Pest still use their process-pool commands.

Reports

The table report gives these robust statistics:

The harness does not report the fastest sample as the result. A low rMAD shows that samples stay close to the median. A wide quartile interval or high rMAD identifies unstable measurements.

The JSON report also contains these items:

Use --seed to reproduce the order. Use --warmups and --runs to change the sample plan. Use --pause-ms to change the pause between commands.

The JSON schema version is 1. PHP INI values describe the harness process. The exact commands record child-process overrides, such as XDEBUG_MODE=coverage. Loaded extensions and INI values do not establish whether every profiler or tracer is active. Record external instrumentation settings with the report.

Q1 and Q3 describe the middle half of the samples. They are not confidence intervals. The relative MAD is the median absolute deviation divided by the median, expressed as a percentage. The harness does not apply a normal-distribution scale factor.

Publication procedure

Use an idle machine with a stable power source and power mode. Stop scheduled work and other variable workloads before the benchmark. Record the processor model and power mode with the JSON report.

Choose the benchmark parameters before you inspect the results. Commit all source changes before a publication run. Publish all raw samples from the chosen run. Do not select the fastest sample or the fastest run.

Do not publish results when sourceTreeDirty is true.

If the distribution is unstable, do not publish a performance claim. Find the cause and execute the complete benchmark again.

Do not compare results from different benchmark shapes, parameters, machines, PHP versions, source revisions, or comparison-tool versions.

Synthetic benchmark results do not predict all real test suites. Use representative application suites before you make a general performance claim.

Published results

The project does not currently publish benchmark numbers. The previous numbers used three unbalanced samples and different output modes. They do not meet the current publication procedure.

Maintenance

CI runs a small benchmark to check the harness:

php tools/benchmark.php --shape=many-fast --scale=1 --workers=2 \
  --warmups=1 --runs=1 --pause-ms=0 --seed=20260821

The project does not publish CI numbers. Shared runners do not give stable performance comparisons.

When the runner changes materially, execute the full benchmark on an idle machine. Update the pinned comparison-tool constants and this page in the same change.