From 95c41da02098bc562743dac1d3bdc20b5e7e0580 Mon Sep 17 00:00:00 2001 From: Dennis Birkholz Date: Thu, 29 Nov 2018 22:50:48 +0100 Subject: [PATCH] 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. --- CHANGELOG.md | 1 + src/PhpSpreadsheet/Reader/Xlsx.php | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baeb4477..d524064c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index eb527475..52ac4705 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -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) { - foreach ($rowsAttributes as $coordRow => $rowAttributes) { - if ($this->getReadFilter() !== null) { - if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + if ($readFilter !== null) { + foreach ($rowsAttributes as $coordRow => $rowAttributes) { + if (!$readFilter->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { continue 2; } } @@ -2583,9 +2585,9 @@ class Xlsx extends BaseReader } foreach ($rowsAttributes as $coordRow => $rowAttributes) { - foreach ($columnsAttributes as $coordColumn => $columnAttributes) { - if ($this->getReadFilter() !== null) { - if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + if ($readFilter !== null) { + foreach ($columnsAttributes as $coordColumn => $columnAttributes) { + if (!$readFilter->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { continue 2; } }