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
This commit is contained in:
Mark Baker 2010-11-20 23:36:20 +00:00
parent 951c332cda
commit 606f43a086
3 changed files with 35 additions and 28 deletions

View File

@ -2320,6 +2320,7 @@ class PHPExcel_Calculation {
// Given two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller // 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); self::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
} }
return array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);
} // function _checkMatrixOperands() } // function _checkMatrixOperands()
@ -3410,12 +3411,25 @@ class PHPExcel_Calculation {
if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return false; if (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return false;
if (!$this->_validateBinaryOperand($cellID,$operand2,$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 // 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 // (converting the other operand to a matrix if need be); then perform the required
// matrix operation // matrix operation
if ((is_array($operand1)) || (is_array($operand2))) { if ((is_array($operand1)) || (is_array($operand2))) {
// Ensure that both operands are arrays/matrices // 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 { try {
// Convert operand 1 from a PHP array to a matrix // Convert operand 1 from a PHP array to a matrix
$matrix = new Matrix($operand1); $matrix = new Matrix($operand1);

View File

@ -80,6 +80,12 @@ class Matrix {
$match = implode(",", array_map('gettype', $args)); $match = implode(",", array_map('gettype', $args));
switch($match) { 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 //Square matrix - n x n
case 'integer': case 'integer':
$this->m = $args[0]; $this->m = $args[0];
@ -105,12 +111,6 @@ class Matrix {
$this->A = array_fill(0, $this->m, array_fill(0, $this->n, $args[2])); $this->A = array_fill(0, $this->m, array_fill(0, $this->n, $args[2]));
break; break;
//Rectangular matrix - m x n initialized from 2D array //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': case 'array,integer,integer':
$this->m = $args[1]; $this->m = $args[1];
$this->n = $args[2]; $this->n = $args[2];

View File

@ -242,29 +242,22 @@ class PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter
$this->_outline_on = 1; $this->_outline_on = 1;
// calculate values for DIMENSIONS record // calculate values for DIMENSIONS record
$_firstRowIndex = 0; $col = $row = array();
$_lastRowIndex = -1;
$_firstColumnIndex = 0;
$_lastColumnIndex = -1;
foreach ($this->_phpSheet->getCellCollection(false) as $cellID) { foreach ($this->_phpSheet->getCellCollection(false) as $cellID) {
list($col,$row) = sscanf($cellID,'%[A-Z]%d'); list($c,$r) = sscanf($cellID,'%[A-Z]%d');
$column = PHPExcel_Cell::columnIndexFromString($col) - 1; $row[$r] = $r;
$col[$c] = strlen($c).$c;
// Don't break Excel!
if ($row >= 65536 or $column >= 256) {
break;
} }
// 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;
$_firstRowIndex = min($_firstRowIndex, $row); $this->_firstColumnIndex = PHPExcel_Cell::columnIndexFromString(substr(min($col),1));
$_lastRowIndex = max($_lastRowIndex, $row); $this->_lastColumnIndex = PHPExcel_Cell::columnIndexFromString(substr(max($col),1));
$_firstColumnIndex = min($_firstColumnIndex, $column); if ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255;
$_lastColumnIndex = max($_lastColumnIndex, $column); if ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255;
}
$this->_firstRowIndex = $_firstRowIndex;
$this->_lastRowIndex = $_lastRowIndex;
$this->_firstColumnIndex = $_firstColumnIndex;
$this->_lastColumnIndex = $_lastColumnIndex;
$this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection()); $this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection());
} }