Cache readFilter access and skip inner loops for empty/default readFilter (#773)

For large XLSX files `Reader/Xlsx::readColumnsAndRowsAttributes()` performs
a lot of calls to `$this->getReadFilter()` and `$this->getReadFilter()->readCell()`
as `readCell()` is called twice for each (possibbly filled) cell.

By ignoring calls to the DefaultReadFilter implementation (which always returns true),
using no custom read filter will not incur any runtime penalty.

The runtime penaltiy when using a custom read filter is reduced by a third by
caching the read filter into a variable instead of using the getter method.

Fixes issue #772.
This commit is contained in:
Dennis Birkholz 2018-11-29 22:50:48 +01:00 committed by Mark Baker
parent a5eb64c77f
commit 95c41da020
2 changed files with 9 additions and 6 deletions

View File

@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
- Support overriding `DefaultValueBinder::dataTypeForValue()` without overriding `DefaultValueBinder::bindValue()` - [#735](https://github.com/PHPOffice/PhpSpreadsheet/pull/735)
- Mpdf export can exceed pcre.backtrack_limit - [#637](https://github.com/PHPOffice/PhpSpreadsheet/issues/637)
- Fix index overflow on data values array - [#748](https://github.com/PHPOffice/PhpSpreadsheet/pull/748)
- Improve XLSX parsing speed if no readFilter is applied - [#772](https://github.com/PHPOffice/PhpSpreadsheet/issues/772)
## [1.5.0] - 2018-10-21

View File

@ -2564,13 +2564,15 @@ class Xlsx extends BaseReader
}
}
$readFilter = (\get_class($this->getReadFilter()) !== DefaultReadFilter::class ? $this->getReadFilter() : null);
// set columns/rows attributes
$columnsAttributesSet = [];
$rowsAttributesSet = [];
foreach ($columnsAttributes as $coordColumn => $columnAttributes) {
if ($readFilter !== null) {
foreach ($rowsAttributes as $coordRow => $rowAttributes) {
if ($this->getReadFilter() !== null) {
if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
if (!$readFilter->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
continue 2;
}
}
@ -2583,9 +2585,9 @@ class Xlsx extends BaseReader
}
foreach ($rowsAttributes as $coordRow => $rowAttributes) {
if ($readFilter !== null) {
foreach ($columnsAttributes as $coordColumn => $columnAttributes) {
if ($this->getReadFilter() !== null) {
if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
if (!$readFilter->readCell($coordColumn, $coordRow, $docSheet->getTitle())) {
continue 2;
}
}