From 606f43a086c2315567aa34ff9454a0711c316caf Mon Sep 17 00:00:00 2001 From: Mark Baker Date: Sat, 20 Nov 2010 23:36:20 +0000 Subject: [PATCH] Performance tweaks, particularly using standard binary operations rather than matrix operations when working with single cell operands git-svn-id: https://phpexcel.svn.codeplex.com/svn/trunk@64078 2327b42d-5241-43d6-9e2a-de5ac946f064 --- Classes/PHPExcel/Calculation.php | 16 ++++++++- Classes/PHPExcel/Shared/JAMA/Matrix.php | 12 +++---- Classes/PHPExcel/Writer/Excel5/Worksheet.php | 35 ++++++++------------ 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/Classes/PHPExcel/Calculation.php b/Classes/PHPExcel/Calculation.php index d493fdd2..a5e3efb7 100644 --- a/Classes/PHPExcel/Calculation.php +++ b/Classes/PHPExcel/Calculation.php @@ -2320,6 +2320,7 @@ class PHPExcel_Calculation { // Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); } + return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns); } // function _checkMatrixOperands() @@ -3410,12 +3411,25 @@ class PHPExcel_Calculation { if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return false; if (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return false; + $executeMatrixOperation = false; // If either of the operands is a matrix, we need to treat them both as matrices // (converting the other operand to a matrix if need be); then perform the required // matrix operation if ((is_array($operand1)) || (is_array($operand2))) { // Ensure that both operands are arrays/matrices - self::_checkMatrixOperands($operand1,$operand2,2); + $executeMatrixOperation = true; + $mSize = array(); + list($mSize[],$mSize[],$mSize[],$mSize[]) = self::_checkMatrixOperands($operand1,$operand2,2); + + // But if they're both single cell matrices, then we can treat them as simple values + if (array_sum($mSize) == 4) { + $executeMatrixOperation = false; + $operand1 = $operand1[0][0]; + $operand2 = $operand2[0][0]; + } + } + + if ($executeMatrixOperation) { try { // Convert operand 1 from a PHP array to a matrix $matrix = new Matrix($operand1); diff --git a/Classes/PHPExcel/Shared/JAMA/Matrix.php b/Classes/PHPExcel/Shared/JAMA/Matrix.php index ca2fa0a2..33fe7813 100644 --- a/Classes/PHPExcel/Shared/JAMA/Matrix.php +++ b/Classes/PHPExcel/Shared/JAMA/Matrix.php @@ -80,6 +80,12 @@ class Matrix { $match = implode(",", array_map('gettype', $args)); switch($match) { + //Rectangular matrix - m x n initialized from 2D array + case 'array': + $this->m = count($args[0]); + $this->n = count($args[0][0]); + $this->A = $args[0]; + break; //Square matrix - n x n case 'integer': $this->m = $args[0]; @@ -105,12 +111,6 @@ class Matrix { $this->A = array_fill(0, $this->m, array_fill(0, $this->n, $args[2])); break; //Rectangular matrix - m x n initialized from 2D array - case 'array': - $this->m = count($args[0]); - $this->n = count($args[0][0]); - $this->A = $args[0]; - break; - //Rectangular matrix - m x n initialized from 2D array case 'array,integer,integer': $this->m = $args[1]; $this->n = $args[2]; diff --git a/Classes/PHPExcel/Writer/Excel5/Worksheet.php b/Classes/PHPExcel/Writer/Excel5/Worksheet.php index 95108a65..3c7dea85 100644 --- a/Classes/PHPExcel/Writer/Excel5/Worksheet.php +++ b/Classes/PHPExcel/Writer/Excel5/Worksheet.php @@ -242,29 +242,22 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter $this->_outline_on = 1; // calculate values for DIMENSIONS record - $_firstRowIndex = 0; - $_lastRowIndex = -1; - $_firstColumnIndex = 0; - $_lastColumnIndex = -1; - + $col = $row = array(); foreach ($this->_phpSheet->getCellCollection(false) as $cellID) { - list($col,$row) = sscanf($cellID,'%[A-Z]%d'); - $column = PHPExcel_Cell::columnIndexFromString($col) - 1; - - // Don't break Excel! - if ($row >= 65536 or $column >= 256) { - break; - } - - $_firstRowIndex = min($_firstRowIndex, $row); - $_lastRowIndex = max($_lastRowIndex, $row); - $_firstColumnIndex = min($_firstColumnIndex, $column); - $_lastColumnIndex = max($_lastColumnIndex, $column); + list($c,$r) = sscanf($cellID,'%[A-Z]%d'); + $row[$r] = $r; + $col[$c] = strlen($c).$c; } - $this->_firstRowIndex = $_firstRowIndex; - $this->_lastRowIndex = $_lastRowIndex; - $this->_firstColumnIndex = $_firstColumnIndex; - $this->_lastColumnIndex = $_lastColumnIndex; + // Determine lowest and highest column and row + $this->_firstRowIndex = min($row); + $this->_lastRowIndex = max($row); + if ($this->_firstRowIndex > 65535) $this->_firstRowIndex = 65535; + if ($this->_lastRowIndex > 65535) $this->_lastRowIndex = 65535; + + $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString(substr(min($col),1)); + $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString(substr(max($col),1)); + if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255; + if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255; $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); }