Skip to content
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
@weirdan

Description

@weirdan

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) {

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions