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)); }
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 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); } }
/** * It should throw an exception if getStats is called when an exception has been set. * * @expectedException RuntimeException * @expectedExceptionMessage Cannot retrieve stats when an exception */ public function testGetStatsWithExceptionException() { $variant = new Variant($this->subject->reveal(), $this->parameterSet->reveal(), 4, 20); $this->subject->getRetryThreshold()->willReturn(10); $variant->createIteration(TestUtil::createResults(4, 10)); $variant->createIteration(TestUtil::createResults(4, 10)); $variant->createIteration(TestUtil::createResults(4, 10)); $variant->createIteration(TestUtil::createResults(4, 10)); $variant->computeStats(); $variant->setException(new \Exception('Test')); $variant->getStats(); }