diff --git a/analyzer/src/BitOne/PhpMemInfo/Analyzer/StdClassShapesCollector.php b/analyzer/src/BitOne/PhpMemInfo/Analyzer/StdClassShapesCollector.php new file mode 100644 index 0000000..3bdd16a --- /dev/null +++ b/analyzer/src/BitOne/PhpMemInfo/Analyzer/StdClassShapesCollector.php @@ -0,0 +1,54 @@ +items = $items; + } + + /** + * Create a summary from the existing items, + * aggregated by member list and sorted by count. + * + * @return array + */ + public function collect() + { + $summary = []; + + foreach ($this->items as $item) { + if ( $item['type'] !== 'object' || $item['class'] !== 'stdClass') { + continue; + } + $shape = implode(',', array_keys($item['children'] ?? [])); + if (!isset($summary[$shape])) { + $summary[$shape] = ['count' => 0, 'self_size' => 0]; + } + $summary[$shape]['count']++; + $summary[$shape]['self_size']+= $item['size']; + } + + uasort($summary, function ($a, $b) { + if ($a === $b) { + return 0; + } + if ($a['count'] > $b['count']) { + return -1; + } else { + return 1; + } + } + ); + + return $summary; + } +} diff --git a/analyzer/src/BitOne/PhpMemInfo/Console/Application.php b/analyzer/src/BitOne/PhpMemInfo/Console/Application.php index 6c9bcb4..67b99fd 100644 --- a/analyzer/src/BitOne/PhpMemInfo/Console/Application.php +++ b/analyzer/src/BitOne/PhpMemInfo/Console/Application.php @@ -7,6 +7,7 @@ use BitOne\PhpMemInfo\Console\Command\SummaryCommand; use BitOne\PhpMemInfo\Console\Command\TopChildrenCommand; use BitOne\PhpMemInfo\Console\Command\TopSizeCommand; +use BitOne\PhpMemInfo\Console\Command\StdClassShapesCommand; use Symfony\Component\Console\Application as BaseApplication; /** @@ -24,5 +25,6 @@ public function __construct() $this->add(new ReferencePathCommand()); $this->add(new SummaryCommand()); $this->add(new TopChildrenCommand()); + $this->add(new StdClassShapesCommand()); } } diff --git a/analyzer/src/BitOne/PhpMemInfo/Console/Command/StdClassShapesCommand.php b/analyzer/src/BitOne/PhpMemInfo/Console/Command/StdClassShapesCommand.php new file mode 100644 index 0000000..3d8ba9a --- /dev/null +++ b/analyzer/src/BitOne/PhpMemInfo/Console/Command/StdClassShapesCommand.php @@ -0,0 +1,63 @@ +setName('stdclass-shapes') + ->setDescription('Show statistics on stdClass property names') + ->addArgument( + 'dump-file', + InputArgument::REQUIRED, + 'PHP Meminfo Dump File in JSON format' + ); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $dumpFilename = $input->getArgument('dump-file'); + $loader = new Loader(); + $items = $loader->load($dumpFilename); + $shapes = (new StdClassShapesCollector($items))->collect(); + $table = new Table($output); + $this->formatTable($shapes, $table); + $table->render(); + return 0; + } + + /** + * Format data into a detailed table. + * + * @param array $shapes + * @param Table $table + */ + protected function formatTable(array $shapes, Table $table) + { + $table->setHeaders(['Members', 'Instances Count', 'Cumulated Self Size (bytes)']); + + $rows = []; + + foreach($shapes as $members => $stats) { + $rows[] = [$members, $stats['count'], $stats['self_size']]; + } + + $table->setRows($rows); + } + +}