8167070: Performance regression in compound scopes
authormcimadamore
Wed, 05 Oct 2016 13:06:21 +0100
changeset 41441 8fb8d9c6c687
parent 41440 abd777fa486c
child 41442 14db641d4a9f
8167070: Performance regression in compound scopes Summary: Extra call to inner scope's hasNext() causes performance regression Reviewed-by: jlahoda
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java	Tue Oct 04 18:56:03 2016 -0700
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Iterators.java	Wed Oct 05 13:06:21 2016 +0100
@@ -46,7 +46,8 @@
 
         private final Iterator<I> inputs;
         private final Function<I, Iterator<O>> convertor;
-        private Iterator<O> currentIterator;
+        @SuppressWarnings("unchecked")
+        private Iterator<O> currentIterator = EMPTY;
 
         public CompoundIterator(Iterable<I> inputs, Function<I, Iterator<O>> convertor) {
             this.inputs = inputs.iterator();
@@ -54,10 +55,10 @@
         }
 
         public boolean hasNext() {
-            while (inputs.hasNext() && (currentIterator == null || !currentIterator.hasNext())) {
-                currentIterator = convertor.apply(inputs.next());
+            if (currentIterator != null && !currentIterator.hasNext()) {
+                update();
             }
-            return currentIterator != null && currentIterator.hasNext();
+            return currentIterator != null;
         }
 
         public O next() {
@@ -70,5 +71,25 @@
         public void remove() {
             throw new UnsupportedOperationException();
         }
+
+        private void update() {
+            while (inputs.hasNext()) {
+                currentIterator = convertor.apply(inputs.next());
+                if (currentIterator.hasNext()) return;
+            }
+            currentIterator = null;
+        }
     }
+
+    @SuppressWarnings("rawtypes")
+    private final static Iterator EMPTY = new Iterator() {
+        public boolean hasNext() {
+            return false;
+        }
+
+        @Override
+        public Object next() {
+            return null;
+        }
+    };
 }