public function formatIterationsShortSummary(Variant $variant) { $subject = $variant->getSubject(); $stats = $variant->getStats(); $timeUnit = $this->timeUnit->resolveDestUnit($variant->getSubject()->getOutputTimeUnit()); $mode = $this->timeUnit->resolveMode($subject->getOutputMode()); $precision = $this->timeUnit->resolvePrecision($subject->getOutputTimePrecision()); return sprintf('[μ Mo]/r: %s %s μRSD/r: %s%%', $this->timeUnit->format($stats->getMean(), $timeUnit, $mode, $precision, false), $this->timeUnit->format($stats->getMode(), $timeUnit, $mode, $precision, false), number_format($stats->getRstdev(), 2)); }
/** * {@inheritdoc} */ public function variantEnd(Variant $variant) { if ($variant->hasErrorStack()) { $this->output->write(sprintf("[0G %-30s<error>ERROR</error>", $variant->getSubject()->getName())); $this->output->write(PHP_EOL); return; } $this->output->write(sprintf("\t%s", $this->formatIterationsFullSummary($variant))); $this->output->write(PHP_EOL); }
public function variantEnd(Variant $variant) { // do not show reject runs if ($variant->getRejectCount() > 0) { return; } $dot = $variant->hasErrorStack() ? '<error>E</error>' : '.'; if ($this->isCi) { $this->output->write($dot); return; } $this->buffer .= $dot; $this->output->write(sprintf("\r%s ", $this->buffer)); }
protected function renderCollectionStatus(Variant $variant) { $this->output->write(PHP_EOL); $this->output->write("[0J"); // clear the line $this->output->write(PHP_EOL); $this->output->write(sprintf('<info>subject</info> %s<info> with </info>%s<info> iteration(s) of </info>%s<info> rev(s),</info>', sprintf('%s', $variant->getSubject()->getName()), count($variant), $variant->getRevolutions())); $this->output->write(PHP_EOL); $this->output->write(sprintf('<info>parameters</info> %s', json_encode($variant->getParameterSet()->getArrayCopy(), true))); $this->output->write(PHP_EOL); $this->output->write("[" . 4 . 'A'); // put the cursor back to the line with the measurements $this->output->write("[0G"); // put the cursor back at col 0 }
private function processVariant(Subject $subject, Variant $variant, \DOMElement $subjectEl) { $variantEl = $subjectEl->appendElement('variant'); // TODO: These attributes should be on the subject, see // https://github.com/phpbench/phpbench/issues/307 $variantEl->setAttribute('sleep', $subject->getSleep()); $variantEl->setAttribute('output-time-unit', $subject->getOutputTimeUnit() ?: TimeUnit::MICROSECONDS); $variantEl->setAttribute('output-time-precision', $subject->getOutputTimePrecision()); $variantEl->setAttribute('output-mode', $subject->getOutputMode() ?: TimeUnit::MODE_TIME); $variantEl->setAttribute('revs', $variant->getRevolutions()); $variantEl->setAttribute('warmup', $variant->getWarmup()); $variantEl->setAttribute('retry-threshold', $subject->getRetryThreshold()); foreach ($variant->getParameterSet() as $name => $value) { $this->createParameter($variantEl, $name, $value); } if ($variant->hasErrorStack()) { $errorsEl = $variantEl->appendElement('errors'); foreach ($variant->getErrorStack() as $error) { $errorEl = $errorsEl->appendElement('error', $error->getMessage()); $errorEl->setAttribute('exception-class', $error->getClass()); $errorEl->setAttribute('code', $error->getCode()); $errorEl->setAttribute('file', $error->getFile()); $errorEl->setAttribute('line', $error->getLine()); } return; } $stats = $variant->getStats(); $stats = iterator_to_array($stats); $resultClasses = []; // ensure same order (for testing) ksort($stats); foreach ($variant as $iteration) { $iterationEl = $variantEl->appendElement('iteration'); foreach ($iteration->getResults() as $result) { // we need to store the class FQNs of the results for deserialization later. if (!isset($resultClasses[$result->getKey()])) { $resultClasses[$result->getKey()] = get_class($result); } $prefix = $result->getKey(); $metrics = $result->getMetrics(); foreach ($metrics as $key => $value) { $iterationEl->setAttribute(sprintf('%s-%s', $prefix, str_replace('_', '-', $key)), $value); } } } $statsEl = $variantEl->appendElement('stats'); foreach ($stats as $statName => $statValue) { $statsEl->setAttribute($statName, $statValue); } foreach ($resultClasses as $resultKey => $classFqn) { if ($subjectEl->queryOne('ancestor::suite/result[@key="' . $resultKey . '"]')) { continue; } $resultEl = $subjectEl->queryOne('ancestor::suite')->appendElement('result'); $resultEl->setAttribute('key', $resultKey); $resultEl->setAttribute('class', $classFqn); } }
/** * {@inheritdoc} */ public function variantEnd(Variant $variant) { if ($variant->getRejectCount() > 0) { return; } $subject = $variant->getSubject(); if ($variant->hasErrorStack()) { $this->output->writeln(sprintf(' t%-30s <error>ERROR</error>', $subject->getName())); return; } $this->output->writeln(sprintf(" %-30s I%s P%s\t%s", $subject->getName(), $variant->count(), $variant->getParameterSet()->getIndex(), $this->formatIterationsFullSummary($variant))); }
private function processVariant(Variant $variant, \DOMElement $variantEl, array $resultClasses) { $errorEls = $variantEl->query('.//error'); if ($errorEls->length) { $errors = []; foreach ($errorEls as $errorEl) { $error = new Error($errorEl->nodeValue, $errorEl->getAttribute('exception-class'), $errorEl->getAttribute('code'), $errorEl->getAttribute('file'), $errorEl->getAttribute('line'), ''); $errors[] = $error; } $variant->createErrorStack($errors); return; } foreach ($variantEl->query('./iteration') as $iterationEl) { $results = []; foreach ($iterationEl->attributes as $attributeEl) { $name = $attributeEl->name; if (false === strpos($name, '-')) { throw new \RuntimeException(sprintf('Expected attribute name to have a result key prefix, got "%s".', $name)); } $prefix = substr($name, 0, strpos($name, '-')); if (!isset($resultClasses[$prefix])) { throw new \RuntimeException(sprintf('No result class was provided with key "%s" for attribute "%s"', $prefix, $name)); } $suffix = substr($name, strpos($name, '-') + 1); $results[$prefix][str_replace('-', '_', $suffix)] = $attributeEl->value; } $iteration = $variant->createIteration(); foreach ($results as $resultKey => $resultData) { $iteration->setResult(call_user_func_array([$resultClasses[$resultKey], 'fromArray'], [$resultData])); } } // TODO: Serialize statistics .. $variant->computeStats(); }
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(Variant $variant, array $specials, $tag) { $this->output->write("[2K"); // clear line $timeUnit = $variant->getSubject()->getOutputTimeUnit(); $outputMode = $variant->getSubject()->getOutputMode(); $lines = []; $line = sprintf('%-' . self::INDENT . 's', '#' . $variant->getSubject()->getIndex()); $nbIterations = $variant->count(); for ($index = 0; $index < $nbIterations; $index++) { $iteration = $variant->getIteration($index); $displayTime = $this->formatIterationTime($iteration); if (isset($specials[$iteration->getIndex()])) { $displayTime = sprintf('<%s>%' . $this->colWidth . 's</%s>', $tag, $displayTime, $tag); } $line .= $displayTime; if ($index > 0 && $index < $nbIterations - 1 && ($index + 1) % self::NUMBER_COLS == 0) { $lines[] = $line; $line = str_repeat(' ', self::INDENT); } } $lines[] = $line; $this->currentLine = count($lines) - 1; $output = trim(implode(PHP_EOL, $lines)); $output .= sprintf(' (%s)', $this->timeUnit->getDestSuffix($this->timeUnit->resolveDestUnit($timeUnit), $this->timeUnit->resolveMode($outputMode))); $this->output->write(sprintf("%s[0J", $output)); // clear rest of the line }
/** * It should return times and memories. */ public function testGetMetricValues() { $variant = new Variant($this->subject->reveal(), $this->parameterSet->reveal(), 1, 0); $variant->createIteration(TestUtil::createResults(4, 100)); $variant->createIteration(TestUtil::createResults(8, 200)); $times = $variant->getMetricValuesByRev(TimeResult::class, 'net'); $memories = $variant->getMetricValues(MemoryResult::class, 'peak'); $this->assertEquals([4, 8], $times); $this->assertEquals([100, 200], $memories); }