From b47af067e6cc8fe7fcbbb4ebc1cefeb4b43fdbba Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 28 Oct 2017 00:39:52 +0200 Subject: [PATCH] dropped ES6 support for iterators --- .../collections/_spec/iterators.spec.ts | 5 +- .../collections/_spec/segmentation.spec.ts | 3 +- .../collections/integer/impl/segmentation.ts | 16 ++--- src/mol-base/collections/iterator.ts | 43 ++++---------- src/mol-data/_spec/atom-set.spec.ts | 4 +- src/mol-data/atom-set/base.ts | 19 +++--- src/perf-tests/iterators.ts | 59 +++++++++++-------- src/perf-tests/sets.ts | 8 ++- 8 files changed, 73 insertions(+), 84 deletions(-) diff --git a/src/mol-base/collections/_spec/iterators.spec.ts b/src/mol-base/collections/_spec/iterators.spec.ts index fba704b58..d5b34f527 100644 --- a/src/mol-base/collections/_spec/iterators.spec.ts +++ b/src/mol-base/collections/_spec/iterators.spec.ts @@ -8,7 +8,10 @@ import Iterator from '../iterator' function iteratorToArray<T>(it: Iterator<T>): T[] { const ret = []; - for (let v = it.move(); !it.done; v = it.move()) ret[ret.length] = v; + while (it.hasNext) { + const v = it.move(); + ret[ret.length] = v; + } return ret; } diff --git a/src/mol-base/collections/_spec/segmentation.spec.ts b/src/mol-base/collections/_spec/segmentation.spec.ts index cac55f128..27b3708fd 100644 --- a/src/mol-base/collections/_spec/segmentation.spec.ts +++ b/src/mol-base/collections/_spec/segmentation.spec.ts @@ -22,7 +22,8 @@ describe('segments', () => { const it = Segmentation.segments(segs, data); const t = Object.create(null); - for (let s = it.move(); !it.done; s = it.move()) { + while (it.hasNext) { + const s = it.move(); for (let j = s.start; j < s.end; j++) { const x = t[s.index]; const v = OrderedSet.getAt(data, j); diff --git a/src/mol-base/collections/integer/impl/segmentation.ts b/src/mol-base/collections/integer/impl/segmentation.ts index af0dc2488..542b4daf2 100644 --- a/src/mol-base/collections/integer/impl/segmentation.ts +++ b/src/mol-base/collections/integer/impl/segmentation.ts @@ -33,21 +33,15 @@ class SegmentIterator implements Iterator<Segs.Segment> { private value: Segs.Segment = { index: 0, start: 0, end: 0 }; private last: number = 0; - [Symbol.iterator]() { return new SegmentIterator(this.segments, this.set, this.inputRange); }; - done: boolean = false; - - next() { - const value = this.move(); - return { value, done: this.done } - } + hasNext: boolean = false; move() { - this.done = this.segmentEnd <= this.segmentStart; - while (!this.done) { + while (this.hasNext) { if (!this.updateValue()) { this.updateSegmentRange(); } else { this.value.index = this.segmentStart++; + this.hasNext = this.segmentEnd > this.segmentStart; break; } } @@ -73,10 +67,10 @@ class SegmentIterator implements Iterator<Segs.Segment> { const max = OrderedSet.getAt(this.set, Interval.max(this.setRange)); this.segmentStart = this.getSegmentIndex(min); this.segmentEnd = this.getSegmentIndex(max) + 1; - this.done = this.segmentEnd <= this.segmentStart; + this.hasNext = this.segmentEnd > this.segmentStart; } - constructor(private segments: OrderedSet, private set: OrderedSet, private inputRange: Interval) { + constructor(private segments: OrderedSet, private set: OrderedSet, inputRange: Interval) { this.last = OrderedSet.max(segments); this.setRange = inputRange; this.updateSegmentRange(); diff --git a/src/mol-base/collections/iterator.ts b/src/mol-base/collections/iterator.ts index 8024ecde8..9d4ff64d6 100644 --- a/src/mol-base/collections/iterator.ts +++ b/src/mol-base/collections/iterator.ts @@ -10,12 +10,10 @@ * "Idiomatic" usage is to use the move function, because it does not make any allocations. * * const it = ...; - * for (let v = it.move(); !it.done; v = it.move()) { ... } + * while (it.hasNext) { const v = it.move(); ... } */ interface Iterator<T> { - [Symbol.iterator](): Iterator<T>, - readonly done: boolean, - next(): { done: boolean, value: T }, + readonly hasNext: boolean, move(): T } @@ -25,24 +23,18 @@ class ArrayIteratorImpl<T> implements Iterator<T> { private length: number = 0; private lastValue: T; - [Symbol.iterator]() { return new ArrayIteratorImpl(this.xs); }; - done: boolean; - - next() { - const value = this.move(); - return { value, done: this.done }; - } + hasNext: boolean; move() { - const index = ++this.index; - if (index < this.length) this.lastValue = this.xs[index]; - else this.done = true; + ++this.index; + this.lastValue = this.xs[this.index]; + this.hasNext = this.index < this.length - 1; return this.lastValue; } constructor(xs: ArrayLike<T>) { this.length = xs.length; - this.done = xs.length === 0; + this.hasNext = xs.length > 0; this.xs = xs; this.index = -1; // try to avoid deoptimization with undefined values @@ -53,32 +45,23 @@ class ArrayIteratorImpl<T> implements Iterator<T> { class RangeIteratorImpl implements Iterator<number> { private value: number; - [Symbol.iterator]() { return new RangeIteratorImpl(this.min, this.max); }; - done: boolean; - - next() { - const value = this.move(); - return { value, done: this.done } - } + hasNext: boolean; move() { ++this.value; - this.done = this.value > this.max; + this.hasNext = this.value < this.max; return this.value; } - constructor(private min: number, private max: number) { + constructor(min: number, private max: number) { this.value = min - 1; - this.done = max < min; + this.hasNext = max >= min; } } class ValueIterator<T> implements Iterator<T> { - private yielded = false; - [Symbol.iterator]() { return new ValueIterator(this.value); }; - done = false; - next() { const value = this.move(); return { value, done: this.done } } - move() { this.done = this.yielded; this.yielded = true; return this.value; } + hasNext = true; + move() { this.hasNext = false; return this.value; } constructor(private value: T) { } } diff --git a/src/mol-data/_spec/atom-set.spec.ts b/src/mol-data/_spec/atom-set.spec.ts index 4239e2af8..f5c1d8e78 100644 --- a/src/mol-data/_spec/atom-set.spec.ts +++ b/src/mol-data/_spec/atom-set.spec.ts @@ -14,7 +14,9 @@ describe('atom set', () => { function setToPairs(set: AtomSet): ArrayLike<IntTuple> { const ret: IntTuple[] = []; const it = AtomSet.atoms(set); - for (let v = it.move(); !it.done; v = it.move()) ret[ret.length] = v; + while (it.hasNext) { + ret[ret.length] = it.move(); + } return ret; } diff --git a/src/mol-data/atom-set/base.ts b/src/mol-data/atom-set/base.ts index 5df7aa753..eeec45449 100644 --- a/src/mol-data/atom-set/base.ts +++ b/src/mol-data/atom-set/base.ts @@ -142,23 +142,18 @@ class ElementsIterator implements Iterator<Tuple> { private currentSize = 0; private currentSet: OrderedSet = OrderedSet.Empty; - [Symbol.iterator]() { return new ElementsIterator(this.elements); }; - done: boolean; - next() { const value = this.move(); return { value, done: this.done } } + hasNext: boolean = false; move() { - if (this.done) return Tuple.Zero; - - if (this.currentIndex >= this.currentSize) { - if (!this.advance()) return Tuple.Zero; - } - - return Tuple.create(this.unit, OrderedSet.getAt(this.currentSet, this.currentIndex++)); + if (!this.hasNext) return Tuple.Zero; + const ret = Tuple.create(this.unit, OrderedSet.getAt(this.currentSet, this.currentIndex++)); + if (this.currentIndex >= this.currentSize) this.advance(); + return ret; } private advance() { if (++this.setIndex >= this.keyCount) { - this.done = true; + this.hasNext = false; return false; } this.unit = OrderedSet.getAt(this.elements.keys, this.setIndex); @@ -170,7 +165,7 @@ class ElementsIterator implements Iterator<Tuple> { constructor(private elements: AtomSetElements) { this.keyCount = OrderedSet.size(elements.keys); - this.done = this.keyCount === 0; + this.hasNext = this.keyCount > 0; this.advance(); } } diff --git a/src/perf-tests/iterators.ts b/src/perf-tests/iterators.ts index 78cfac0a3..b2f10b3fd 100644 --- a/src/perf-tests/iterators.ts +++ b/src/perf-tests/iterators.ts @@ -1,4 +1,5 @@ import * as B from 'benchmark' +import It from '../mol-base/collections/iterator' function createData(n: number) { const data = [];//new Int32Array(n); @@ -10,7 +11,7 @@ function createData(n: number) { return data; } -namespace Iterators { +export namespace Iterators { const data = createData(100000); export function forLoop() { @@ -31,13 +32,13 @@ namespace Iterators { export function forEach() { const ctx = { sum: 0 }; - data.forEach(function(this: typeof ctx, v: number) { this.sum += v }, ctx); + data.forEach(function (this: typeof ctx, v: number) { this.sum += v }, ctx); return ctx.sum; } export function forEachAllParams() { const ctx = { sum: 0 }; - data.forEach(function(this: typeof ctx, v: number, _: any, __: any) { this.sum += v }, ctx); + data.forEach(function (this: typeof ctx, v: number, _: any, __: any) { this.sum += v }, ctx); return ctx.sum; } @@ -200,28 +201,34 @@ namespace Iterators { } return sum; } -} + export function run() { + const suite = new B.Suite(); + + suite + .add('for', () => Iterators.forLoop()) + .add('forOf', () => Iterators.forOf()) + .add('forEach', () => Iterators.forEach()) + .add('forEach all params', () => Iterators.forEachAllParams()) + .add('forEachClosure', () => Iterators.forEachClosure()) + .add('forEachClosure all', () => Iterators.forEachClosureAll()) + .add('forEachClosure all function', () => Iterators.forEachClosureAllFunction()) + .add('mutableIterator ES6', () => Iterators.mutableES6Iterator()) + //.add('mutableIteratorOf ES6', () => Iterators.mutableES6IteratorOf()) + .add('immutableIterator ES6', () => Iterators.immutableES6Iterator()) + //.add('immutableIteratorOf ES6', () => Iterators.immutableES6IteratorOf()) + .add('mutableIterator', () => Iterators.mutableIterator()) + .on('cycle', (e: any) => { + console.log(String(e.target)); + }) + // .on('complete', function (this: any) { + // console.log('Fastest is ' + this.filter('fastest').map('name')); + // }) + .run(); + } +} -const suite = new B.Suite(); - -suite - .add('for', () => Iterators.forLoop()) - .add('forOf', () => Iterators.forOf()) - .add('forEach', () => Iterators.forEach()) - .add('forEach all params', () => Iterators.forEachAllParams()) - .add('forEachClosure', () => Iterators.forEachClosure()) - .add('forEachClosure all', () => Iterators.forEachClosureAll()) - .add('forEachClosure all function', () => Iterators.forEachClosureAllFunction()) - .add('mutableIterator ES6', () => Iterators.mutableES6Iterator()) - //.add('mutableIteratorOf ES6', () => Iterators.mutableES6IteratorOf()) - .add('immutableIterator ES6', () => Iterators.immutableES6Iterator()) - //.add('immutableIteratorOf ES6', () => Iterators.immutableES6IteratorOf()) - .add('mutableIterator', () => Iterators.mutableIterator()) - .on('cycle', (e: any) => { - console.log(String(e.target)); - }) - // .on('complete', function (this: any) { - // console.log('Fastest is ' + this.filter('fastest').map('name')); - // }) - .run(); \ No newline at end of file +const it = It.Array([1, 2, 3]); +while (it.hasNext) { + console.log(it.move()); +} \ No newline at end of file diff --git a/src/perf-tests/sets.ts b/src/perf-tests/sets.ts index e5fc1e389..178a9d9fe 100644 --- a/src/perf-tests/sets.ts +++ b/src/perf-tests/sets.ts @@ -29,7 +29,10 @@ export namespace Iteration { export function iterators() { let s = 0; const it = AtomSet.atoms(ms); - for (let v = it.move(); !it.done; v = it.move()) s += Tuple.snd(v); + while (it.hasNext) { + const v = it.move(); + s += Tuple.snd(v); + } return s; } @@ -274,7 +277,8 @@ export function testSegments() { const segs = Segmentation.create(SortedArray.ofSortedArray([0, 4, 10, 12, 13, 15, 25]), []); const it = Segmentation.segments(segs, data); - for (let s = it.move(); !it.done; s = it.move()) { + while (it.hasNext) { + const s = it.move(); for (let j = s.start; j < s.end; j++) { console.log(`${s.index}: ${OrdSet.getAt(data, j)}`); } -- GitLab