/** * Run all benchmarks (or all applicable benchmarks) in the given path. * * The $name argument will set the "name" attribute on the "suite" element. * * @param string $contextName * @param string $path */ public function run(RunnerContext $context) { $dom = new SuiteDocument(); $rootEl = $dom->createElement('phpbench'); $rootEl->setAttribute('version', PhpBench::VERSION); $dom->appendChild($rootEl); $suiteEl = $rootEl->appendElement('suite'); $suiteEl->setAttribute('context', $context->getContextName()); $suiteEl->setAttribute('date', date('c')); $suiteEl->setAttribute('config-path', $this->configPath); $suiteEl->setAttribute('retry-threshold', $context->getRetryThreshold($this->retryThreshold)); $collection = $this->collectionBuilder->buildCollection($context->getPath(), $context->getFilters(), $context->getGroups()); $this->logger->startSuite($dom); /* @var BenchmarkMetadata */ foreach ($collection->getBenchmarks() as $benchmark) { $benchmarkEl = $dom->createElement('benchmark'); $benchmarkEl->setAttribute('class', $benchmark->getClass()); $this->logger->benchmarkStart($benchmark); $this->runBenchmark($context, $benchmark, $benchmarkEl); $this->logger->benchmarkEnd($benchmark); $suiteEl->appendChild($benchmarkEl); } $this->logger->endSuite($dom); return $dom; }
/** * Run all benchmarks (or all applicable benchmarks) in the given path. * * The $name argument will set the "name" attribute on the "suite" element. * * @param string $contextName * @param string $path */ public function run(RunnerContext $context) { $executorConfig = $this->executorRegistry->getConfig($context->getExecutor()); $executor = $this->executorRegistry->getService($executorConfig['executor']); $dom = new SuiteDocument(); $rootEl = $dom->createElement('phpbench'); $rootEl->setAttribute('version', PhpBench::VERSION); $dom->appendChild($rootEl); $suiteEl = $rootEl->appendElement('suite'); $suiteEl->setAttribute('context', $context->getContextName()); $suiteEl->setAttribute('date', date('c')); $suiteEl->setAttribute('config-path', $this->configPath); $suiteEl->setAttribute('retry-threshold', $context->getRetryThreshold($this->retryThreshold)); // add environmental information. $this->appendEnvironment($suiteEl); // build the collection of benchmarks to be executed. $collection = $this->collectionBuilder->buildCollection($context->getPath(), $context->getFilters(), $context->getGroups()); // log the start of the suite run. $this->logger->startSuite($dom); /* @var BenchmarkMetadata */ foreach ($collection->getBenchmarks() as $benchmark) { $benchmarkEl = $dom->createElement('benchmark'); $benchmarkEl->setAttribute('class', $benchmark->getClass()); $this->logger->benchmarkStart($benchmark); $this->runBenchmark($executor, $context, $benchmark, $benchmarkEl); $this->logger->benchmarkEnd($benchmark); $suiteEl->appendChild($benchmarkEl); } $this->logger->endSuite($dom); return $dom; }
public function execute(InputInterface $input, OutputInterface $output) { $reports = $input->getOption('report'); $reportNames = $this->reportManager->processCliReports($reports); $files = $input->getOption('file'); $outputs = $input->getOption('output'); $outputNames = $this->reportManager->processCliOutputs($outputs); if (!$files) { throw new \InvalidArgumentException('You must specify at least one result --file (generated by the run command\'s `--dump-file=` option)'); } if (!$reportNames) { throw new \InvalidArgumentException('You must specify or configure at least one report, e.g.: --report=default'); } $aggregateDom = new SuiteDocument(); $aggregateEl = $aggregateDom->createRoot('phpbench'); foreach ($files as $file) { if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('Could not find suite result file "%s" (cwd: %s)', $file, getcwd())); } $suiteResult = new SuiteDocument(); $suiteResult->loadXml(file_get_contents($file)); foreach ($suiteResult->xpath()->query('//suite') as $suiteEl) { $suiteEl = $aggregateDom->importNode($suiteEl, true); if (!$suiteEl->getAttribute('name')) { $suiteEl->setAttribute('name', basename($file)); } $aggregateEl->appendChild($suiteEl); } } $this->reportManager->renderReports($output, $aggregateDom, $reportNames, $outputNames); }
private function getSuiteDocument() { $suite = new SuiteDocument(); $suite->loadXml(<<<EOT <?xml version="1.0"?> <phpbench version="0.x"> <benchmark class="Foobar"> <subject name="mySubject"> <variant> <parameter name="foo" value="bar" /> <parameter name="array" type="collection"> <parameter name="0" value="one" /> <parameter name="1" value="two" /> </parameter> <parameter name="assoc_array" type="collection"> <parameter name="one" value="two" /> <parameter name="three" value="four" /> </parameter> <iteration time="100" memory="100" revs="1" /> <iteration time="75" memory="100" revs="1" /> </variant> </subject> </benchmark> </phpbench> EOT ); return $suite; }
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; }
public function execute(InputInterface $input, OutputInterface $output) { $reports = $input->getOption('report'); $reportNames = $this->reportManager->processCliReports($reports); $file = $input->getArgument('file'); if (!$reportNames) { throw new \InvalidArgumentException('You must specify or configure at least one report, e.g.: --report=simple'); } if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('Could not find suite result file "%s"', $file)); } $suiteResult = new SuiteDocument(); $suiteResult->loadXml(file_get_contents($file)); $this->reportManager->generateReports($output, $suiteResult, $reportNames); }
protected function doGenerate($definition, SuiteDocument $document, Config $config, array $parameters = array()) { if ($config['debug']) { $this->output->writeln('<info>Suite XML</info>'); $this->output->writeln($document->saveXML()); } $definition = $this->definitionLoader->load($definition, $document); if (isset($config['pretty_params']) && true === $config['pretty_params']) { $definition['classes']['params'] = array(array('json_format', array())); } if (array_key_exists('formatting', $config) && $config['formatting'] === false) { foreach ($definition['classes'] as &$class) { $class = array(); } } $tableDom = $this->tabular->tabulate($document, $definition, $parameters); if ($config['exclude']) { foreach ($config['exclude'] as $cellName) { $excludeCells = $tableDom->xpath()->query(sprintf('//cell[@name="%s"]', $cellName)); foreach ($excludeCells as $excludeCell) { $excludeCell->parentNode->removeChild($excludeCell); } } } $reportDom = new Document(); $reportEl = $reportDom->createRoot('reports'); $reportEl->setAttribute('name', $config->getName()); $reportEl = $reportEl->appendElement('report'); if ($config['debug']) { $tableDom->formatOutput = true; $this->output->writeln('<info>Table XML</info>'); $this->output->writeln($tableDom->saveXML()); } if ($config['title']) { $reportEl->setAttribute('title', $config['title']); } if ($config['description']) { $reportEl->appendElement('description', $config['description']); } $tableEl = $reportEl->ownerDocument->importNode($tableDom->firstChild, true); $reportEl->appendChild($tableEl); return $reportEl->ownerDocument; }
protected function doGenerate($definition, SuiteDocument $document, array $config, array $parameters = array()) { if ($config['debug']) { $this->output->writeln('<info>Suite XML</info>'); $this->output->writeln($document->saveXML()); } $tableDom = $this->tabular->tabulate($document, $definition, $parameters); if ($config['debug']) { $tableDom->formatOutput = true; $this->output->writeln('<info>Table XML</info>'); $this->output->writeln($tableDom->saveXML()); } if ($config['title']) { $this->output->writeln(sprintf('<title>%s</title>', $config['title'])); } if ($config['description']) { $this->output->writeln(sprintf('<description>%s</description>', $config['description'])); } $this->render($tableDom, $config); }
public function execute(InputInterface $input, OutputInterface $output) { $files = $input->getOption('file'); if (!$files) { throw new \InvalidArgumentException('You must specify at least one result --file (generated by the run command\'s `--dump-file=` option)'); } if (!$input->getOption('report')) { throw new \InvalidArgumentException('You must specify or configure at least one report, e.g.: --report=default'); } $this->timeUnitHandler->timeUnitFromInput($input); $aggregateDom = new SuiteDocument(); $aggregateDom->createRoot('phpbench'); foreach ($files as $file) { if (!file_exists($file)) { throw new \InvalidArgumentException(sprintf('Could not find suite result file "%s" (cwd: %s)', $file, getcwd())); } $suiteResult = new SuiteDocument(); $suiteResult->loadXml(file_get_contents($file)); $aggregateDom->appendSuiteDocument($suiteResult, basename($file)); } $this->reportHandler->reportsFromInput($input, $output, $aggregateDom); }
public function endSuite(SuiteDocument $suiteDocument) { if ($suiteDocument->hasErrors()) { $errorStacks = $suiteDocument->getErrorStacks(); $this->output->write(PHP_EOL); $this->output->writeln(sprintf('%d subjects encountered errors:', count($errorStacks))); $this->output->write(PHP_EOL); foreach ($errorStacks as $errorStack) { $this->output->writeln(sprintf('<error>%s</error>', $errorStack['subject'])); $this->output->write(PHP_EOL); foreach ($errorStack['exceptions'] as $exception) { $this->output->writeln(sprintf(' %s %s', $exception['exception_class'], str_replace("\n", "\n ", $exception['message']))); } } } $this->output->writeln(sprintf('%s subjects, %s iterations, %s revs, %s rejects', $suiteDocument->getNbSubjects(), $suiteDocument->getNbIterations(), $suiteDocument->getNbRevolutions(), $suiteDocument->getNbRejects())); $this->output->writeln(sprintf('(best [mean mode] worst) = %s [%s %s] %s (%s)', number_format($this->timeUnit->toDestUnit($suiteDocument->getMinTime()), 3), number_format($this->timeUnit->toDestUnit($suiteDocument->getMeanTime()), 3), number_format($this->timeUnit->toDestUnit($suiteDocument->getModeTime()), 3), number_format($this->timeUnit->toDestUnit($suiteDocument->getMaxTime()), 3), $this->timeUnit->getDestSuffix())); $this->output->writeln(sprintf('⅀T: %s μSD/r %s μRSD/r: %s%%', $this->timeUnit->format($suiteDocument->getTotalTime(), null, TimeUnit::MODE_TIME), $this->timeUnit->format($suiteDocument->getMeanStDev(), null, TimeUnit::MODE_TIME), number_format($suiteDocument->getMeanRelStDev(), 3))); }
private function getMultipleSuiteDocument() { $suite = new SuiteDocument(); $suite->loadXml(<<<EOT <?xml version="1.0"?> <phpbench version="0.x"> <suite context="foobar"> <benchmark class="Foobar"> <subject name="mySubject"> <variant output-time-unit="microseconds"> <iteration time="100" memory="100" revs="1" deviation="1" rejection-count="0"/> <iteration time="75" memory="100" revs="1" deviation="2" rejection-count="0"/> </variant> </subject> </benchmark> </suite> <suite context="barfoo"> <benchmark class="Foobar"> <subject name="mySubject"> <variant output-time-unit="microseconds"> <iteration time="100" memory="100" revs="1" deviation="1" rejection-count="0"/> <iteration time="75" memory="100" revs="1" deviation="2" rejection-count="0"/> </variant> </subject> </benchmark> </suite> </phpbench> EOT ); return $suite; }
/** * It should throw an exception if the append target has no phpbench root element. * * @expectedException InvalidArgumentException */ public function testAppendSuiteDocumentException() { $suiteDocument = new SuiteDocument(); $newSuiteDocument = $this->getSuiteDocument(); $suiteDocument->appendSuiteDocument($newSuiteDocument, 'foo'); }
public function endSuite(SuiteDocument $suiteDocument) { $this->output->writeln(sprintf('%s subjects, %s iterations, %s revs, %s rejects', $suiteDocument->getNbSubjects(), $suiteDocument->getNbIterations(), $suiteDocument->getNbRevolutions(), $suiteDocument->getNbRejects())); $this->output->writeln(sprintf('min mean max: %s %s %s (%s/r)', number_format($this->timeUnit->value($suiteDocument->getMin()), 3), number_format($this->timeUnit->value($suiteDocument->getMeanTime()), 3), number_format($this->timeUnit->value($suiteDocument->getMax()), 3), $this->timeUnit->getDestSuffix())); $this->output->writeln(sprintf('⅀T: %s%s μSD/r %s%s μRSD/r: %s%%', number_format($this->timeUnit->value($suiteDocument->getTotalTime()), 3), $this->timeUnit->getDestSuffix(), number_format($this->timeUnit->value($suiteDocument->getMeanStDev()), 3), $this->timeUnit->getDestSuffix(), number_format($suiteDocument->getMeanRelStDev(), 3))); }
/** * Append the suites container in another document to this document. * * @param SuiteDocument $suiteDocument * @param string $defaultName */ public function appendSuiteDocument(SuiteDocument $suiteDocument, $defaultName = null) { $aggregateEl = $this->evaluate('/phpbench')->item(0); if (null === $aggregateEl) { throw new \InvalidArgumentException('Suite document must have root element "phpbench" before appending other suites'); } foreach ($suiteDocument->xpath()->query('//suite') as $suiteEl) { $suiteEl = $this->importNode($suiteEl, true); if (!$suiteEl->getAttribute('name')) { $suiteEl->setAttribute('name', $defaultName); } $aggregateEl->appendChild($suiteEl); } }
/** * Run all benchmarks (or all applicable benchmarks) in the given path. * * @param string */ public function runAll($path) { $dom = new SuiteDocument(); $suiteEl = $dom->createElement('phpbench'); $suiteEl->setAttribute('version', PhpBench::VERSION); $collection = $this->collectionBuilder->buildCollection($path, $this->subjectsOverride, $this->groups); foreach ($collection->getBenchmarks() as $benchmark) { $benchmarkEl = $dom->createElement('benchmark'); $benchmarkEl->setAttribute('class', $benchmark->getClassFqn()); $this->logger->benchmarkStart($benchmark); $this->run($benchmark, $benchmarkEl); $this->logger->benchmarkEnd($benchmark); $suiteEl->appendChild($benchmarkEl); } $dom->appendChild($suiteEl); return $dom; }