diff --git a/package-lock.json b/package-lock.json index 65edb5b9cf7b351137a82ca276ff669f2ff6c1ec..fbf52d4b90d0f4e49c73635a1e0e111e5f3bff45 100644 Binary files a/package-lock.json and b/package-lock.json differ diff --git a/package.json b/package.json index ae74e31e7843cfcee96df6862a932c6d13e567e9..a024c317721b89e841d890b053bfa501c0fb2fa5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "./node_modules/.bin/jest", "dist": "./node_modules/.bin/uglifyjs build/js/molio.dev.js -cm > dist/molio.js && cp build/js/molio.esm.js dist/molio.esm.js", "script": "./node_modules/.bin/rollup build/js/src/script.js -e fs -f cjs -o build/js/script.js", - "runscript": "npm run script && node build/js/script.js", + "runscript": "node build/js/src/script.js", "download-dics": "./node_modules/.bin/download -o build/dics http://mmcif.wwpdb.org/dictionaries/ascii/mmcif_pdbx_v50.dic && ./node_modules/.bin/download -o build/dics http://mmcif.wwpdb.org/dictionaries/ascii/mmcif_ddl.dic" }, "jest": { @@ -29,8 +29,10 @@ "author": "", "license": "MIT", "devDependencies": { - "@types/jest": "^21.1.2", - "@types/node": "^8.0.34", + "@types/benchmark": "^1.0.30", + "@types/jest": "^21.1.3", + "@types/node": "^8.0.41", + "benchmark": "^2.1.4", "download-cli": "^1.0.5", "jest": "^21.2.1", "rollup": "^0.50.0", @@ -42,7 +44,7 @@ "ts-jest": "^21.1.2", "tslint": "^5.7.0", "typescript": "^2.5.3", - "uglify-js": "^3.1.3", + "uglify-js": "^3.1.4", "util.promisify": "^1.0.0" }, "dependencies": {} diff --git a/src/perf-tests/iterators.ts b/src/perf-tests/iterators.ts new file mode 100644 index 0000000000000000000000000000000000000000..78cfac0a3040c93dfd8986fab738bcade047938f --- /dev/null +++ b/src/perf-tests/iterators.ts @@ -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(); \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 21016d5620035aa70f28141cd4fcef5f015af6f6..be84a2ed208b5a0ed417753663cc9278d629c953 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,13 @@ { "compilerOptions": { - "target": "es6", + "target": "es5", "alwaysStrict": true, "noImplicitAny": true, "noImplicitThis": true, "sourceMap": false, "noUnusedLocals": true, "strictNullChecks": true, + //"downlevelIteration": true, "lib": [ "es6", "dom" ], "outDir": "build/js/src" },