[Console] Improve Table performance

This commit is contained in:
Roland Franssen 2017-07-18 23:08:49 +02:00 committed by Fabien Potencier
parent 1ec2219773
commit 2c9922e8af
2 changed files with 71 additions and 34 deletions

View File

@ -275,29 +275,40 @@ class Table
*/ */
public function render() public function render()
{ {
$this->calculateNumberOfColumns(); $rows = array_merge($this->headers, array($divider = new TableSeparator()), $this->rows);
$rows = $this->buildTableRows($this->rows); $this->calculateNumberOfColumns($rows);
$headers = $this->buildTableRows($this->headers);
$this->calculateColumnsWidth(array_merge($headers, $rows)); $rows = $this->buildTableRows($rows);
$this->calculateColumnsWidth($rows);
$this->renderRowSeparator(); $isHeader = true;
if (!empty($headers)) { $isFirstRow = false;
foreach ($headers as $header) {
$this->renderRow($header, $this->style->getCellHeaderFormat());
$this->renderRowSeparator();
}
}
foreach ($rows as $row) { foreach ($rows as $row) {
if ($divider === $row) {
$isHeader = false;
$isFirstRow = true;
continue;
}
if ($row instanceof TableSeparator) { if ($row instanceof TableSeparator) {
$this->renderRowSeparator(); $this->renderRowSeparator();
} else {
$this->renderRow($row, $this->style->getCellRowFormat()); continue;
} }
if (!$row) {
continue;
}
if ($isHeader || $isFirstRow) {
$this->renderRowSeparator();
if ($isFirstRow) {
$isFirstRow = false;
}
}
$this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat());
} }
if (!empty($rows)) { $this->renderRowSeparator();
$this->renderRowSeparator();
}
$this->cleanup(); $this->cleanup();
} }
@ -340,10 +351,6 @@ class Table
*/ */
private function renderRow(array $row, string $cellFormat) private function renderRow(array $row, string $cellFormat)
{ {
if (empty($row)) {
return;
}
$rowContent = $this->renderColumnSeparator(); $rowContent = $this->renderColumnSeparator();
foreach ($this->getRowColumns($row) as $column) { foreach ($this->getRowColumns($row) as $column) {
$rowContent .= $this->renderCell($row, $column, $cellFormat); $rowContent .= $this->renderCell($row, $column, $cellFormat);
@ -386,14 +393,10 @@ class Table
/** /**
* Calculate number of columns for this table. * Calculate number of columns for this table.
*/ */
private function calculateNumberOfColumns() private function calculateNumberOfColumns($rows)
{ {
if (null !== $this->numberOfColumns) {
return;
}
$columns = array(0); $columns = array(0);
foreach (array_merge($this->headers, $this->rows) as $row) { foreach ($rows as $row) {
if ($row instanceof TableSeparator) { if ($row instanceof TableSeparator) {
continue; continue;
} }
@ -429,15 +432,17 @@ class Table
} }
} }
$tableRows = array(); return new TableRows(function () use ($rows, $unmergedRows) {
foreach ($rows as $rowKey => $row) { foreach ($rows as $rowKey => $row) {
$tableRows[] = $this->fillCells($row); yield $this->fillCells($row);
if (isset($unmergedRows[$rowKey])) {
$tableRows = array_merge($tableRows, $unmergedRows[$rowKey]);
}
}
return $tableRows; if (isset($unmergedRows[$rowKey])) {
foreach ($unmergedRows[$rowKey] as $row) {
yield $row;
}
}
}
});
} }
/** /**

View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Helper;
/**
* @internal
*/
class TableRows implements \IteratorAggregate
{
private $generator;
public function __construct(callable $generator)
{
$this->generator = $generator;
}
public function getIterator()
{
$g = $this->generator;
return $g();
}
}