]> source.dussan.org Git - poi.git/commitdiff
bug 57840: cache XSSFEvaluationCell and XSSFEvaluationSheet instances (30% evaluation...
authorJaven O'Neal <onealj@apache.org>
Sat, 11 Jun 2016 02:10:32 +0000 (02:10 +0000)
committerJaven O'Neal <onealj@apache.org>
Sat, 11 Jun 2016 02:10:32 +0000 (02:10 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1747838 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFEvaluationWorkbook.java

index d0b3f3b1a45d1ec86096b0f7580fbce1c242e268..329f78f3edb1a2542e80eb7a4063f249a37eec2c 100644 (file)
 
 package org.apache.poi.xssf.usermodel;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.poi.ss.formula.EvaluationCell;
 import org.apache.poi.ss.formula.EvaluationSheet;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
 
 /**
  * XSSF wrapper for a sheet under evaluation
@@ -26,6 +31,7 @@ import org.apache.poi.ss.formula.EvaluationSheet;
 final class XSSFEvaluationSheet implements EvaluationSheet {
 
        private final XSSFSheet _xs;
+       private Map<CellKey, EvaluationCell> _cellCache;
 
        public XSSFEvaluationSheet(XSSFSheet sheet) {
                _xs = sheet;
@@ -35,14 +41,46 @@ final class XSSFEvaluationSheet implements EvaluationSheet {
                return _xs;
        }
        public EvaluationCell getCell(int rowIndex, int columnIndex) {
-               XSSFRow row = _xs.getRow(rowIndex);
-               if (row == null) {
-                       return null;
-               }
-               XSSFCell cell = row.getCell(columnIndex);
-               if (cell == null) {
-                       return null;
-               }
-               return new XSSFEvaluationCell(cell, this);
+           // cache for performance: ~30% speedup due to caching
+           if (_cellCache == null) {
+               _cellCache = new HashMap<CellKey, EvaluationCell>(_xs.getLastRowNum()*3);
+               for (final Row row : _xs) {
+                    final int rowNum = row.getRowNum();
+                   for (final Cell cell : row) {
+                       // cast is safe, the iterator is just defined using the interface
+                        final CellKey key = new CellKey(rowNum, cell.getColumnIndex());
+                        final EvaluationCell evalcell = new XSSFEvaluationCell((XSSFCell) cell, this);
+                       _cellCache.put(key, evalcell);
+                   }
+               }
+           }
+           
+           return _cellCache.get(new CellKey(rowIndex, columnIndex));
+               
+       }
+       
+       private static class CellKey {
+           private final int _row;
+           private final int _col;
+           private final int _hash;
+           
+           protected CellKey(int row, int col) {
+               _row = row;
+               _col = col;
+               _hash = (17 * 37 + row) * 37 + col;
+           }
+           
+           @Override
+           public int hashCode() {
+               return _hash;
+           }
+           
+           @Override
+           public boolean equals(Object obj) {
+               if (obj == null) return false;
+               // assumes other object is one of us, otherwise ClassCastException is thrown
+               final CellKey oKey = (CellKey) obj;
+               return _row == oKey._row && _col == oKey._col;
+           }
        }
 }
index 46e5a54a6cb2ac5ae744d99551847b7feffcd945..413a1fab2b1d36401728e61ca145809a1684def4 100644 (file)
@@ -27,6 +27,8 @@ import org.apache.poi.ss.formula.ptg.Ptg;
  * Internal POI use only
  */
 public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
+    private XSSFEvaluationSheet[] _sheetCache;
+    
     public static XSSFEvaluationWorkbook create(XSSFWorkbook book) {
         if (book == null) {
             return null;
@@ -46,7 +48,21 @@ public final class XSSFEvaluationWorkbook extends BaseXSSFEvaluationWorkbook {
 
     @Override
     public EvaluationSheet getSheet(int sheetIndex) {
-        return new XSSFEvaluationSheet(_uBook.getSheetAt(sheetIndex));
+        // Performance optimization: build sheet cache the first time this is called
+        // to avoid re-creating the XSSFEvaluationSheet each time a new cell is evaluated
+        // EvaluationWorkbooks make not guarentee to syncronize changes made to
+        // the underlying workbook after the EvaluationWorkbook is created.
+        if (_sheetCache == null) {
+            _sheetCache = new XSSFEvaluationSheet[_uBook.getNumberOfSheets()];
+            for (int i=0; i < _uBook.getNumberOfSheets(); i++) {
+                _sheetCache[i] = new XSSFEvaluationSheet(_uBook.getSheetAt(i));
+            }
+        }
+        if (sheetIndex < 0 || sheetIndex >= _sheetCache.length) {
+            // do this to reuse the out-of-bounds logic and message from XSSFWorkbook
+            _uBook.getSheetAt(sheetIndex);
+        }
+        return _sheetCache[sheetIndex];
     }
 
     @Override