From 980e409768d4fbf94bcd87b572bb357253a69921 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 19:50:17 +0400 Subject: [PATCH] Optimize integer progression iterators With the help of ProgressionUtil hasNext and next* consist now of only several bytecode instructions --- runtime/src/jet/ByteProgressionIterator.java | 18 +++++++++++++---- runtime/src/jet/CharProgressionIterator.java | 18 +++++++++++++---- runtime/src/jet/IntProgressionIterator.java | 20 ++++++++++++------- runtime/src/jet/LongProgressionIterator.java | 20 ++++++++++++------- runtime/src/jet/ShortProgressionIterator.java | 18 +++++++++++++---- 5 files changed, 68 insertions(+), 26 deletions(-) diff --git a/runtime/src/jet/ByteProgressionIterator.java b/runtime/src/jet/ByteProgressionIterator.java index 85243e18f2f..fc5fc8417bc 100644 --- a/runtime/src/jet/ByteProgressionIterator.java +++ b/runtime/src/jet/ByteProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class ByteProgressionIterator extends ByteIterator { private int next; - private final byte end; private final int increment; + private final byte finalElement; + private boolean hasNext; public ByteProgressionIterator(byte start, byte end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (byte) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public byte nextByte() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (byte) value; } } diff --git a/runtime/src/jet/CharProgressionIterator.java b/runtime/src/jet/CharProgressionIterator.java index dc608162f9f..cb09aeb5347 100644 --- a/runtime/src/jet/CharProgressionIterator.java +++ b/runtime/src/jet/CharProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class CharProgressionIterator extends CharIterator { private int next; - private final char end; private final int increment; + private final char finalElement; + private boolean hasNext; public CharProgressionIterator(char start, char end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (char) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public char nextChar() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (char) value; } } diff --git a/runtime/src/jet/IntProgressionIterator.java b/runtime/src/jet/IntProgressionIterator.java index 3d7dda17af8..0b6f9bb5175 100644 --- a/runtime/src/jet/IntProgressionIterator.java +++ b/runtime/src/jet/IntProgressionIterator.java @@ -16,29 +16,35 @@ package jet; +import jet.runtime.ProgressionUtil; + class IntProgressionIterator extends IntIterator { private int next; - private final int end; private final int increment; - private boolean overflowHappened = false; + private final int finalElement; + private boolean hasNext; public IntProgressionIterator(int start, int end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return !overflowHappened && (increment > 0 ? next <= end : next >= end); + return hasNext; } @Override public int nextInt() { int value = next; - next += increment; - if ((increment > 0) != (next > value)) { - overflowHappened = true; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; } return value; } diff --git a/runtime/src/jet/LongProgressionIterator.java b/runtime/src/jet/LongProgressionIterator.java index f6c613cf3fa..70493e39972 100644 --- a/runtime/src/jet/LongProgressionIterator.java +++ b/runtime/src/jet/LongProgressionIterator.java @@ -16,29 +16,35 @@ package jet; +import jet.runtime.ProgressionUtil; + class LongProgressionIterator extends LongIterator { private long next; - private final long end; private final long increment; - private boolean overflowHappened = false; + private final long finalElement; + private boolean hasNext; public LongProgressionIterator(long start, long end, long increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return !overflowHappened && (increment > 0 ? next <= end : next >= end); + return hasNext; } @Override public long nextLong() { long value = next; - next += increment; - if ((increment > 0) != (next > value)) { - overflowHappened = true; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; } return value; } diff --git a/runtime/src/jet/ShortProgressionIterator.java b/runtime/src/jet/ShortProgressionIterator.java index cd3b77200f9..d3da9e80326 100644 --- a/runtime/src/jet/ShortProgressionIterator.java +++ b/runtime/src/jet/ShortProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class ShortProgressionIterator extends ShortIterator { private int next; - private final short end; private final int increment; + private final short finalElement; + private boolean hasNext; public ShortProgressionIterator(short start, short end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (short) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public short nextShort() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (short) value; } }