You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2015/12/15 23:23:48 UTC

[07/23] incubator-freemarker git commit: Replaced localContextStack with specialized ArrayList-like class for some speed gain

Replaced localContextStack with specialized ArrayList-like class for some speed gain


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/325bbd08
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/325bbd08
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/325bbd08

Branch: refs/heads/2.3
Commit: 325bbd088a841725014da68078cda76258f2c9df
Parents: 079b701
Author: ddekany <dd...@apache.org>
Authored: Sun Dec 6 01:45:52 2015 +0100
Committer: ddekany <dd...@apache.org>
Committed: Sun Dec 6 01:45:52 2015 +0100

----------------------------------------------------------------------
 src/main/java/freemarker/core/Environment.java  | 26 ++++++-------
 .../java/freemarker/core/IteratorBlock.java     |  2 +-
 .../java/freemarker/core/LocalContextStack.java | 39 ++++++++++++++++++++
 src/main/java/freemarker/core/Macro.java        |  5 +--
 4 files changed, 53 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/325bbd08/src/main/java/freemarker/core/Environment.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Environment.java b/src/main/java/freemarker/core/Environment.java
index 08c10d0..dcc178a 100644
--- a/src/main/java/freemarker/core/Environment.java
+++ b/src/main/java/freemarker/core/Environment.java
@@ -159,7 +159,7 @@ public final class Environment extends Configurable {
 
     private Writer out;
     private Macro.Context currentMacroContext;
-    private ArrayList localContextStack;
+    private LocalContextStack localContextStack;
     private final Namespace mainNamespace;
     private Namespace currentNamespace, globalNamespace;
     private HashMap loadedLibs;
@@ -377,7 +377,7 @@ public final class Environment extends Configurable {
             directiveModel.execute(this, args, outArgs, nested);
         } finally {
             if (outArgs.length > 0) {
-                popLocalContext();
+                localContextStack.pop();
             }
         }
     }
@@ -500,7 +500,7 @@ public final class Environment extends Configurable {
      */
     void invokeNestedContent(BodyInstruction.Context bodyCtx) throws TemplateException, IOException {
         Macro.Context invokingMacroContext = getCurrentMacroContext();
-        ArrayList prevLocalContextStack = localContextStack;
+        LocalContextStack prevLocalContextStack = localContextStack;
         TemplateElement nestedContent = invokingMacroContext.nestedContent;
         if (nestedContent != null) {
             this.currentMacroContext = invokingMacroContext.prevMacroContext;
@@ -523,7 +523,7 @@ public final class Environment extends Configurable {
                 visit(nestedContent);
             } finally {
                 if (invokingMacroContext.nestedContentParameterNames != null) {
-                    popLocalContext();
+                    localContextStack.pop();
                 }
                 this.currentMacroContext = invokingMacroContext;
                 currentNamespace = getMacroNamespace(invokingMacroContext.getMacro());
@@ -549,7 +549,7 @@ public final class Environment extends Configurable {
             handleTemplateException(te);
             return true;
         } finally {
-            popLocalContext();
+            localContextStack.pop();
         }
     }
 
@@ -655,7 +655,7 @@ public final class Environment extends Configurable {
             final Macro.Context prevMacroCtx = currentMacroContext;
             currentMacroContext = macroCtx;
 
-            final ArrayList prevLocalContextStack = localContextStack;
+            final LocalContextStack prevLocalContextStack = localContextStack;
             localContextStack = null;
 
             final Namespace prevNamespace = currentNamespace;
@@ -1813,7 +1813,7 @@ public final class Environment extends Configurable {
     public TemplateModel getLocalVariable(String name) throws TemplateModelException {
         if (localContextStack != null) {
             for (int i = localContextStack.size() - 1; i >= 0; i--) {
-                LocalContext lc = (LocalContext) localContextStack.get(i);
+                LocalContext lc = localContextStack.get(i);
                 TemplateModel tm = lc.getLocalVariable(name);
                 if (tm != null) {
                     return tm;
@@ -1940,7 +1940,7 @@ public final class Environment extends Configurable {
         }
         if (localContextStack != null) {
             for (int i = localContextStack.size() - 1; i >= 0; i--) {
-                LocalContext lc = (LocalContext) localContextStack.get(i);
+                LocalContext lc = localContextStack.get(i);
                 set.addAll(lc.getLocalVariableNames());
             }
         }
@@ -2101,16 +2101,12 @@ public final class Environment extends Configurable {
 
     private void pushLocalContext(LocalContext localContext) {
         if (localContextStack == null) {
-            localContextStack = new ArrayList();
+            localContextStack = new LocalContextStack();
         }
-        localContextStack.add(localContext);
+        localContextStack.push(localContext);
     }
 
-    private void popLocalContext() {
-        localContextStack.remove(localContextStack.size() - 1);
-    }
-
-    ArrayList getLocalContextStack() {
+    LocalContextStack getLocalContextStack() {
         return localContextStack;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/325bbd08/src/main/java/freemarker/core/IteratorBlock.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/IteratorBlock.java b/src/main/java/freemarker/core/IteratorBlock.java
index e6c760b..62c6e34 100644
--- a/src/main/java/freemarker/core/IteratorBlock.java
+++ b/src/main/java/freemarker/core/IteratorBlock.java
@@ -89,7 +89,7 @@ final class IteratorBlock extends TemplateElement {
      */
     static IterationContext findEnclosingIterationContext(Environment env, String loopVariableName)
             throws _MiscTemplateException {
-        ArrayList ctxStack = env.getLocalContextStack();
+        LocalContextStack ctxStack = env.getLocalContextStack();
         if (ctxStack != null) {
             for (int i = ctxStack.size() - 1; i >= 0; i--) {
                 Object ctx = ctxStack.get(i);

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/325bbd08/src/main/java/freemarker/core/LocalContextStack.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/LocalContextStack.java b/src/main/java/freemarker/core/LocalContextStack.java
new file mode 100644
index 0000000..5f556bf
--- /dev/null
+++ b/src/main/java/freemarker/core/LocalContextStack.java
@@ -0,0 +1,39 @@
+package freemarker.core;
+
+/**
+ * Class that's a little bit more efficient than using an {@code ArrayList<LocalContext>}. 
+ * 
+ * @since 2.3.24
+ */
+final class LocalContextStack {
+
+    private LocalContext[] buffer = new LocalContext[8];
+    private int size;
+
+    void push(LocalContext localContext) {
+        final int newSize = ++size;
+        LocalContext[] buffer = this.buffer;
+        if (buffer.length < newSize) {
+            final LocalContext[] newBuffer = new LocalContext[newSize * 2];
+            for (int i = 0; i < buffer.length; i++) {
+                newBuffer[i] = buffer[i];
+            }
+            buffer = newBuffer;
+            this.buffer = newBuffer;
+        }
+        buffer[newSize - 1] = localContext;
+    }
+
+    void pop() {
+        buffer[--size] = null;
+    }
+
+    public LocalContext get(int index) {
+        return buffer[index];
+    }
+    
+    public int size() {
+        return size;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/325bbd08/src/main/java/freemarker/core/Macro.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/core/Macro.java b/src/main/java/freemarker/core/Macro.java
index 5310947..d639d4f 100644
--- a/src/main/java/freemarker/core/Macro.java
+++ b/src/main/java/freemarker/core/Macro.java
@@ -20,7 +20,6 @@
 package freemarker.core;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
@@ -160,13 +159,13 @@ public final class Macro extends TemplateElement implements TemplateModel {
         final TemplateElement nestedContent;
         final Environment.Namespace nestedContentNamespace;
         final List nestedContentParameterNames;
-        final ArrayList prevLocalContextStack;
+        final LocalContextStack prevLocalContextStack;
         final Context prevMacroContext;
         
         Context(Environment env, 
                 TemplateElement nestedContent,
                 List nestedContentParameterNames) {
-            this.localVars = env.new Namespace();
+            this.localVars = env.new Namespace(); 
             this.nestedContent = nestedContent;
             this.nestedContentNamespace = env.getCurrentNamespace();
             this.nestedContentParameterNames = nestedContentParameterNames;