|
@@ -0,0 +1,227 @@
|
|
|
|
+import * as B from 'benchmark'
|
|
|
|
+
|
|
|
|
+function createData(n: number) {
|
|
|
|
+ const data = [];//new Int32Array(n);
|
|
|
|
+ let last = (15 * Math.random()) | 0;
|
|
|
|
+ for (let i = 0; i < n; i++) {
|
|
|
|
+ data[i] = last;
|
|
|
|
+ last += (15 * Math.random()) | 0;
|
|
|
|
+ }
|
|
|
|
+ return data;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+namespace Iterators {
|
|
|
|
+ const data = createData(100000);
|
|
|
|
+
|
|
|
|
+ export function forLoop() {
|
|
|
|
+ let sum = 0;
|
|
|
|
+ for (let i = 0, _i = data.length; i < _i; i++) {
|
|
|
|
+ sum += data[i];
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function forOf() {
|
|
|
|
+ let sum = 0;
|
|
|
|
+ for (const e of data) {
|
|
|
|
+ sum += e;
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function forEach() {
|
|
|
|
+ const ctx = { sum: 0 };
|
|
|
|
+ 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);
|
|
|
|
+ return ctx.sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function forEachClosure() {
|
|
|
|
+ let sum = 0;
|
|
|
|
+ data.forEach(v => sum += v);
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function forEachClosureAll() {
|
|
|
|
+ let sum = 0;
|
|
|
|
+ data.forEach((v, _, __) => sum += v);
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ export function forEachClosureAllFunction() {
|
|
|
|
+ let sum = 0;
|
|
|
|
+ data.forEach(function (v, _, __) { sum += v });
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ interface ES6Iterator {
|
|
|
|
+ [Symbol.iterator](): ES6Iterator,
|
|
|
|
+ done: boolean;
|
|
|
|
+ value: number;
|
|
|
|
+ next(): { done: boolean, value: number }
|
|
|
|
+ reset(data: any[]): ES6Iterator;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class _MutableES6Iterator implements ES6Iterator {
|
|
|
|
+ done = true;
|
|
|
|
+ value = 0;
|
|
|
|
+
|
|
|
|
+ private xs: any[] = void 0 as any;
|
|
|
|
+ private index: number = -1;
|
|
|
|
+ private length: number = 0;
|
|
|
|
+
|
|
|
|
+ [Symbol.iterator]() { return this };
|
|
|
|
+
|
|
|
|
+ next() {
|
|
|
|
+ const index = ++this.index;
|
|
|
|
+ if (index < this.length) this.value = this.xs[index];
|
|
|
|
+ else this.done = true;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ reset(xs: any[]) {
|
|
|
|
+ this.value = xs[0];
|
|
|
|
+ this.length = xs.length;
|
|
|
|
+ this.done = false;
|
|
|
|
+ this.xs = xs;
|
|
|
|
+ this.index = -1;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class _ImmutableES6Iterator implements ES6Iterator {
|
|
|
|
+ done = true;
|
|
|
|
+ value = 0;
|
|
|
|
+
|
|
|
|
+ private xs: any[] = void 0 as any;
|
|
|
|
+ private index: number = -1;
|
|
|
|
+ private length: number = 0;
|
|
|
|
+
|
|
|
|
+ [Symbol.iterator]() { return this };
|
|
|
|
+
|
|
|
|
+ next() {
|
|
|
|
+ const index = ++this.index;
|
|
|
|
+ if (index < this.length) this.value = this.xs[index];
|
|
|
|
+ else this.done = true;
|
|
|
|
+ return { done: this.done, value: this.value };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ reset(xs: any[]) {
|
|
|
|
+ this.value = xs[0];
|
|
|
|
+ this.length = xs.length;
|
|
|
|
+ this.done = false;
|
|
|
|
+ this.xs = xs;
|
|
|
|
+ this.index = -1;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function mutableES6Iterator() {
|
|
|
|
+ const it = new _MutableES6Iterator();
|
|
|
|
+ let sum = 0;
|
|
|
|
+ for (let e = it.reset(data).next().value; !it.done; e = it.next().value) {
|
|
|
|
+ sum += e;
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // export function mutableES6IteratorOf() {
|
|
|
|
+ // const it = new _ImmutableES6Iterator();
|
|
|
|
+ // let sum = 0;
|
|
|
|
+ // for (const e of it.reset(data)) {
|
|
|
|
+ // sum += e;
|
|
|
|
+ // }
|
|
|
|
+ // return sum;
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ export function immutableES6Iterator() {
|
|
|
|
+ const it = new _ImmutableES6Iterator();
|
|
|
|
+ let sum = 0;
|
|
|
|
+ it.reset(data);
|
|
|
|
+ while (true) {
|
|
|
|
+ const { value, done } = it.next();
|
|
|
|
+ if (done) break;
|
|
|
|
+ sum += value;
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // export function immutableES6IteratorOf() {
|
|
|
|
+ // const it = new _MutableES6Iterator();
|
|
|
|
+ // let sum = 0;
|
|
|
|
+ // for (const e of it.reset(data)) {
|
|
|
|
+ // sum += e;
|
|
|
|
+ // }
|
|
|
|
+ // return sum;
|
|
|
|
+ // }
|
|
|
|
+
|
|
|
|
+ interface MutableIterator {
|
|
|
|
+ done: boolean;
|
|
|
|
+ next(): number;
|
|
|
|
+ start(data: any[]): number;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ class _MutableIterator implements MutableIterator {
|
|
|
|
+ done = true;
|
|
|
|
+
|
|
|
|
+ private xs: any[] = void 0 as any;
|
|
|
|
+ private index: number = -1;
|
|
|
|
+ private length: number = 0;
|
|
|
|
+
|
|
|
|
+ next() {
|
|
|
|
+ const index = ++this.index;
|
|
|
|
+ if (index < this.length) return this.xs[index];
|
|
|
|
+ else {
|
|
|
|
+ this.done = true;
|
|
|
|
+ return 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ start(xs: any[]) {
|
|
|
|
+ this.length = xs.length;
|
|
|
|
+ this.done = !this.length;
|
|
|
|
+ this.xs = xs;
|
|
|
|
+ this.index = 0;
|
|
|
|
+ return this.done ? 0 : this.xs[0];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ export function mutableIterator() {
|
|
|
|
+ const it = new _MutableIterator();
|
|
|
|
+ let sum = 0;
|
|
|
|
+ for (let e = it.start(data); !it.done; e = it.next()) {
|
|
|
|
+ sum += e;
|
|
|
|
+ }
|
|
|
|
+ return sum;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+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();
|