Merge pull request #911 from mcculls/dependency-stack-performance
Improve performance of internal DependencyStack collection
diff --git a/core/src/com/google/inject/internal/InternalContext.java b/core/src/com/google/inject/internal/InternalContext.java
index 6a6f7ef..1493c37 100644
--- a/core/src/com/google/inject/internal/InternalContext.java
+++ b/core/src/com/google/inject/internal/InternalContext.java
@@ -23,7 +23,7 @@
import com.google.inject.spi.Dependency;
import com.google.inject.spi.DependencyAndSource;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Map;
@@ -40,13 +40,7 @@
/** Keeps track of the type that is currently being requested for injection. */
private Dependency<?> dependency;
- /**
- * Keeps track of the hierarchy of types needed during injection.
- *
- * <p>This is a pairwise combination of dependencies and sources, with dependencies or keys on
- * even indices, and sources on odd indices. This structure is to avoid the memory overhead of
- * DependencyAndSource objects, which can add to several tens of megabytes in large applications.
- */
+ /** Keeps track of the hierarchy of types needed during injection. */
private final DependencyStack state = new DependencyStack();
@SuppressWarnings("unchecked")
@@ -68,8 +62,7 @@
public Dependency<?> pushDependency(Dependency<?> dependency, Object source) {
Dependency<?> previous = this.dependency;
this.dependency = dependency;
- state.add(dependency);
- state.add(source);
+ state.add(dependency, source);
return previous;
}
@@ -81,8 +74,7 @@
/** Adds to the state without setting the dependency. */
public void pushState(Key<?> key, Object source) {
- state.add(key);
- state.add(source);
+ state.add(key, source);
}
/** Pops from the state without setting a dependency. */
@@ -106,10 +98,36 @@
return builder.build();
}
- private static final class DependencyStack extends ArrayList<Object> {
- void pop() {
- int sz = size();
- removeRange(sz - 2, sz);
+ /**
+ * Keeps track of the hierarchy of types needed during injection.
+ *
+ * <p>This is a pairwise combination of dependencies and sources, with dependencies or keys on
+ * even indices, and sources on odd indices. This structure is to avoid the memory overhead of
+ * DependencyAndSource objects, which can add to several tens of megabytes in large applications.
+ */
+ private static final class DependencyStack {
+ private Object[] elements = new Object[16];
+ private int size = 0;
+
+ public void add(Object dependencyOrKey, Object source) {
+ if (elements.length < size + 2) {
+ elements = Arrays.copyOf(elements, (elements.length*3)/2 + 2);
+ }
+ elements[size++] = dependencyOrKey;
+ elements[size++] = source;
+ }
+
+ public void pop() {
+ elements[--size] = null;
+ elements[--size] = null;
+ }
+
+ public Object get(int i) {
+ return elements[i];
+ }
+
+ public int size() {
+ return size;
}
}
}