This repository was archived by the owner on Jan 2, 2019. It is now read-only.
This repository was archived by the owner on Jan 2, 2019. It is now read-only.
[from codeplex] getCellXfByHashCode could be sped up by introducing cache by hash #192
Open
Description
Initially reported at https://phpexcel.codeplex.com/workitem/19300
I was working on style-heavy excel export recently and, during profiling, noticed that PHPExcel spends about 70% of execution time in PHPExcel::getCellXfByHashCode() (mostly called from PHPExcel_Style::applyFromArray())
It seems that adding a simple array cache to that method improves the speed (in my particular use-case) by a factor of 3, while only increasing memory usage by a negligible amount (cellXfCollection has something like 100 items, and I only store a pointer to an item in the cache).
The proposed patch doesn't break any additional unit tests (but I must note that there's a lot of unit tests broken with a pristine svn copy).
+++ PHPExcel.php (working copy)
@@ -90,6 +90,7 @@
* @var PHPExcel_Style[]
*/
private $_cellXfCollection = array();
+ private $_cellXfHashCache = array();
/**
* CellStyleXf collection
@@ -596,8 +597,13 @@
*/
public function getCellXfByHashCode($pValue = '')
{
- foreach ($this->_cellXfCollection as $cellXf) {
+ if (isset($this->_cellXfHashCache[$pValue]) && isset($this->_cellXfCollection[$this->_cellXfHashCache[$pValue]])) {
+ //logger()->info('ret from cache');
+ return $this->_cellXfCollection[$this->_cellXfHashCache[$pValue]];
+ }
+ foreach ($this->_cellXfCollection as $i => $cellXf) {
if ($cellXf->getHashCode() == $pValue) {
+ $this->_cellXfHashCache[$pValue] = $i;
return $cellXf;
}
}
@@ -627,6 +633,8 @@
{
$this->_cellXfCollection[] = $style;
$style->setIndex(count($this->_cellXfCollection) - 1);
+ // clear cellXfHashCache
+ $this->_cellXfHashCache = array();
}
/**
@@ -640,6 +648,8 @@
if ($pIndex > count($this->_cellXfCollection) - 1) {
throw new Exception("CellXf index is out of bounds.");
} else {
+ // clear cellXfHashCache
+ $this->_cellXfHashCache = array();
// first remove the cellXf
array_splice($this->_cellXfCollection, $pIndex, 1);
@@ -789,6 +799,9 @@
$this->_cellXfCollection[] = new PHPExcel_Style();
}
+ // clear xf hash cache
+ $this->_cellXfHashCache = array();
+
// update the xfIndex for all cells, row dimensions, column dimensions
foreach ($this->getWorksheetIterator() as $sheet) {