public function execute(InputInterface $input, OutputInterface $output) { $outputDir = $this->outputDirHandler->handleOutputDir($input, $output); $guiBin = null; if ($input->getOption('gui')) { $finder = new ExecutableFinder(); $guiBin = $finder->find($input->getOption('gui-bin')); if (null === $guiBin) { throw new \InvalidArgumentException(sprintf('Could not locate GUI bin "%s"', $input->getOption('gui-bin'))); } } $generatedFiles = []; $this->runnerHandler->runFromInput($input, $output, ['executor' => ['executor' => 'xdebug_profile', 'output_dir' => $outputDir, 'callback' => function ($iteration) use($outputDir, $guiBin, &$generatedFiles) { $generatedFiles[] = $generatedFile = $outputDir . DIRECTORY_SEPARATOR . XDebugUtil::filenameFromIteration($iteration, '.cachegrind'); if ($guiBin) { $process = new Process(sprintf($guiBin . ' ' . $generatedFile)); $process->run(); } }], 'iterations' => [1]]); $output->write(PHP_EOL); $output->writeln(sprintf('<info>%s profile(s) generated:</info>', count($generatedFiles))); $output->write(PHP_EOL); foreach ($generatedFiles as $generatedFile) { if (!file_exists($generatedFile)) { throw new \InvalidArgumentException(sprintf('Profile "%s" was not generated. Maybe you do not have XDebug installed?', $generatedFile)); } $output->writeln(sprintf(' %s', $generatedFile)); } }
/** * {@inheritdoc} */ public function launch(Payload $payload, Iteration $iteration, Config $config) { $name = XDebugUtil::filenameFromIteration($iteration); $dir = $config['output_dir']; $phpConfig = ['xdebug.trace_output_name' => $name, 'xdebug.trace_output_dir' => $dir, 'xdebug.trace_format' => '1', 'xdebug.auto_trace' => '1', 'xdebug.coverage_enable' => '0', 'xdebug.collect_params' => '3']; $payload->setPhpConfig($phpConfig); $path = $dir . DIRECTORY_SEPARATOR . $name . '.xt'; // if the file exists, remove it. XDebug might not be installed // on the PHP binary and the file may not be generated. We should // fail in such a case and not use the file from a previous run. if ($this->filesystem->exists($path)) { $this->filesystem->remove($path); } $result = $payload->launch(); if (false === $this->filesystem->exists($path)) { throw new \RuntimeException(sprintf('Trace file at "%s" was not generated.', $path)); } $dom = $this->converter->convert($path); $subject = $iteration->getVariant()->getSubject(); $class = $subject->getBenchmark()->getClass(); // remove leading slash from class name for matching // the class in the trace. if (substr($class, 0, 1) == '\\') { $class = substr($class, 1); } // extract only the timings for the benchmark class, ignore the bootstrapping $selector = '//entry[@function="' . $class . '->' . $subject->getName() . '"]'; // calculate stats from the trace $time = (int) ($dom->evaluate(sprintf('number(%s/@end-time) - number(%s/@start-time)', $selector, $selector)) * 1000000.0); $memory = (int) $dom->evaluate(sprintf('number(%s/@end-memory) - number(%s/@start-memory)', $selector, $selector)); $funcCalls = (int) $dom->evaluate('count(' . $selector . '//*)'); $iteration->setResult(new TimeResult($result['time'])); $iteration->setResult(MemoryResult::fromArray($result['mem'])); $iteration->setResult(new XDebugTraceResult($time, $memory, $funcCalls, $dom)); }
public function execute(InputInterface $input, OutputInterface $output) { $this->output = $output; $outputDir = $input->getOption('outdir'); $guiBin = null; if ($input->getOption('gui')) { $finder = new ExecutableFinder(); $guiBin = $finder->find($input->getOption('gui-bin')); if (null === $guiBin) { throw new \InvalidArgumentException(sprintf('Could not locate GUI bin "%s"', $input->getOption('gui-bin'))); } } if (!$this->filesystem->exists($outputDir)) { $output->writeln(sprintf('<comment>// creating non-existing directory %s</comment>', $outputDir)); $this->filesystem->mkdir($outputDir); } $generatedFiles = array(); $this->runnerHandler->runFromInput($input, $output, array('executor' => array('executor' => 'xdebug', 'output_dir' => $outputDir, 'callback' => function ($iteration) use($outputDir, $guiBin, &$generatedFiles) { $generatedFiles[] = $generatedFile = $outputDir . DIRECTORY_SEPARATOR . XDebugUtil::filenameFromIteration($iteration); if ($guiBin) { $process = new Process(sprintf($guiBin . ' ' . $generatedFile)); $process->run(); } }), 'iterations' => 1)); $output->write(PHP_EOL); $output->writeln(sprintf('<info>%s profile(s) generated:</info>', count($generatedFiles))); $output->write(PHP_EOL); foreach ($generatedFiles as $generatedFile) { if (!file_exists($generatedFile)) { throw new \InvalidArgumentException(sprintf('Profile "%s" was not generated. Maybe you do not have XDebug installed?', $generatedFile)); } $this->output->writeln(sprintf(' %s', $generatedFile)); } }
/** * {@inheritdoc} */ public function launch(Payload $payload, Iteration $iteration, Config $config) { $name = XDebugUtil::filenameFromIteration($iteration); $dir = $config['output_dir']; $phpConfig = ['xdebug.trace_output_name' => $name, 'xdebug.trace_output_dir' => $dir, 'xdebug.trace_format' => '1', 'xdebug.auto_trace' => '1', 'xdebug.coverage_enable' => '0']; $payload->setPhpConfig($phpConfig); $path = $dir . DIRECTORY_SEPARATOR . $name . '.xt'; $result = $payload->launch(); if (false === $this->filesystem->exists($path)) { throw new \RuntimeException(sprintf('Trace file at "%s" was not generated. Is XDebug enabled in the benchmarking environment', $path)); } $dom = $this->converter->convert($path); $subject = $iteration->getVariant()->getSubject(); $class = $subject->getBenchmark()->getClass(); if (substr($class, 0, 1) == '\\') { $class = substr($class, 1); } // extract only the timings for the benchmark class, ignore the bootstrapping $selector = '//entry[@function="' . $class . '->' . $subject->getName() . '"]'; // calculate stats from the trace $time = (int) ($dom->evaluate(sprintf('sum(%s/@end-time) - sum(/@start-time)', $selector, $selector)) * 1000000.0); $memory = (int) $dom->evaluate(sprintf('sum(%s/@end-memory) - sum(/@start-memory)', $selector, $selector)); $funcCalls = (int) $dom->evaluate('count(' . $selector . '//*)'); $iteration->setResult(new TimeResult($result['time'])); $iteration->setResult(MemoryResult::fromArray($result['mem'])); $iteration->setResult(new XDebugTraceResult($time, $memory, $funcCalls)); }
/** * It should generate a filename for an iteration. * * @dataProvider provideGenerate */ public function testGenerate($class, $subject, $expected) { $this->benchmark->getClass()->willReturn($class); $this->subject->getName()->willReturn($subject); $this->parameters->getIndex()->willReturn(7); $this->iteration->getParameters()->willReturn($this->parameters->reveal()); $this->subject->getBenchmarkMetadata()->willReturn($this->benchmark->reveal()); $this->iteration->getSubject()->willReturn($this->subject->reveal()); $result = XDebugUtil::filenameFromIteration($this->iteration->reveal()); $this->assertEquals($expected, $result); }
/** * {@inheritdoc} */ public function launch(Payload $payload, Iteration $iteration, Config $config) { $outputDir = $config['output_dir']; $callback = $config['callback']; $name = XDebugUtil::filenameFromIteration($iteration, '.cachegrind'); $phpConfig = ['xdebug.profiler_enable' => 1, 'xdebug.profiler_output_dir' => PhpBench::normalizePath($outputDir), 'xdebug.profiler_output_name' => $name]; $payload->setPhpConfig($phpConfig); $result = $payload->launch(); if (isset($result['buffer']) && $result['buffer']) { throw new \RuntimeException(sprintf('Benchmark made some noise: %s', $result['buffer'])); } $callback($iteration, $result); $iteration->setResult(new TimeResult($result['time'])); $iteration->setResult(MemoryResult::fromArray($result['mem'])); return $result; }
/** * {@inheritdoc} */ public function launch(Payload $payload, Iteration $iteration, Config $config) { $outputDir = $config['output_dir']; $callback = $config['callback']; $name = XDebugUtil::filenameFromIteration($iteration); $phpConfig = array('xdebug.profiler_enable' => 1, 'xdebug.profiler_output_dir' => $outputDir, 'xdebug.profiler_output_name' => $name); if (!extension_loaded('xdebug')) { $phpConfig['zend_extension'] = 'xdebug.so'; } $payload->setPhpConfig($phpConfig); $result = $payload->launch(); if (isset($result['buffer']) && $result['buffer']) { throw new \RuntimeException(sprintf('Benchmark made some noise: %s', $result['buffer'])); } $result = new IterationResult($result['time'], $result['memory']); $callback($iteration, $result); return $result; }