public function generate(SuiteDocument $results, Config $config) { $document = new Document(); $reportEl = $document->createRoot('reports'); $reportEl->setAttribute('name', $config->getName()); $reportEl = $reportEl->appendElement('report'); $descriptionEl = $reportEl->appendElement('description'); $descriptionEl->nodeValue = <<<EOT Warning: The histogram report is experimental, it may change or be removed without warning in future versions of PHPBench. EOT; $tableEl = $reportEl->appendElement('table'); foreach ($results->query('//subject') as $subjectEl) { foreach ($subjectEl->query('.//variant') as $variantEl) { $times = array(); foreach ($variantEl->query('.//iteration') as $iterationEl) { $times[] = $iterationEl->getAttribute('rev-time'); } if (count($times) > 1) { $histogram = Statistics::histogram($times, $config['bins']); $kde = new Kde($times); $kdeX = Statistics::linspace(min($times), max($times), $config['bins'] + 1); $kdeY = $kde->evaluate($kdeX); } else { $histogram = array((string) current($times) => 1); $kdeY = array(null); } $counter = 0; foreach ($histogram as $xValue => $frequency) { $kdeVal = $kdeY[$counter++]; $rowEl = $tableEl->appendElement('row'); $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'benchmark'); $cellEl->nodeValue = functions\class_name($subjectEl->evaluate('string(ancestor::benchmark/@class)')); $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'subject'); $cellEl->nodeValue = $subjectEl->evaluate('string(./@name)'); $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'index'); $cellEl->nodeValue = $counter; $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'time'); $cellEl->nodeValue = $xValue; $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'freq'); $cellEl->nodeValue = $frequency; $cellEl = $rowEl->appendElement('cell'); $cellEl->setAttribute('name', 'kde'); $cellEl->nodeValue = $kdeVal; } } } return $document; }
/** * It should return histogram data. * * @dataProvider provideHistogram */ public function testHistogram(array $data, $steps, $lower, $upper, array $expected) { $result = Statistics::histogram($data, $steps, $lower, $upper); $this->assertEquals($expected, $result); }
private function drawIterations(Variant $variant) { $subject = $variant->getSubject(); $this->output->write("[2K"); // clear the whole line $this->output->write(PHP_EOL); $this->output->write("[2K"); // clear the whole line $this->output->write("[1A"); $sigma = 2; $bins = 16; if ($variant->isComputed()) { $times = $variant->getMetricValues(ComputedResult::class, 'z_value'); $stats = $variant->getStats(); $freqs = Statistics::histogram($times, $bins, -$sigma, $sigma); } else { $stats = new Distribution([0]); $freqs = array_fill(0, $bins + 1, null); } $this->output->write(sprintf('#%-2d (σ = %s ) -%sσ [', $subject->getIndex(), $this->timeUnit->format($stats->getStdev()), $sigma)); $this->drawBlocks($freqs, $stats); $this->output->write(sprintf('] +%sσ <comment>%s</comment>', $sigma, $variant->isComputed() ? $this->formatIterationsShortSummary($variant) : '')); $this->output->write(PHP_EOL); }
private function drawIterations(IterationCollection $iterations) { $subject = $iterations->getSubject(); $this->output->write("[2K"); // clear the whole line $this->output->write(PHP_EOL); $this->output->write("[2K"); // clear the whole line $this->output->write("[1A"); $sigma = 2; $bins = 16; if ($iterations->isComputed()) { $times = $iterations->getZValues(); $stats = $iterations->getStats(); $freqs = Statistics::histogram($times, $bins, -$sigma, $sigma); } else { $stats = array('stdev' => 0, 'mean' => 0, 'max' => 0); $freqs = array_fill(0, $bins + 1, null); } $this->output->write(sprintf('#%-2d (σ = %s ) -%sσ [', $subject->getIndex(), $this->timeUnit->format($stats['stdev']), $sigma)); $this->drawBlocks($freqs, $stats); $this->output->write(sprintf('] +%sσ <comment>%s</comment>', $sigma, $iterations->isComputed() ? $this->formatIterationsShortSummary($iterations) : '')); $this->output->write(PHP_EOL); }