From cd246b25d6881f8f3ba954f78944dd34e890df33 Mon Sep 17 00:00:00 2001 From: David Sehnal <david.sehnal@gmail.com> Date: Sat, 28 Oct 2017 20:35:44 +0200 Subject: [PATCH] column --- src/mol-base/collections/column.ts | 33 +++++++++++++ src/perf-tests/column.ts | 78 ++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 src/perf-tests/column.ts diff --git a/src/mol-base/collections/column.ts b/src/mol-base/collections/column.ts index 6139a04f4..b9ec618e0 100644 --- a/src/mol-base/collections/column.ts +++ b/src/mol-base/collections/column.ts @@ -35,6 +35,13 @@ namespace Column { end?: number } + export interface LambdaSpec<T extends Type> { + value: (row: number) => T['@type'], + rowCount: number, + type: T, + valueKind?: (row: number) => ValueKind, + } + export interface ArraySpec<T extends Type> { array: ArrayLike<T['@type']>, type: T, @@ -51,6 +58,10 @@ namespace Column { return constColumn(v, rowCount, type, ValueKind.Present); } + export function ofLambda<T extends Type>(spec: LambdaSpec<T>): Column<T['@type']> { + return lambdaColumn(spec); + } + export function ofArray<T extends Column.Type>(spec: Column.ArraySpec<T>): Column<T['@type']> { return arrayColumn(spec); } @@ -92,6 +103,28 @@ function constColumn<T extends Column.Type>(v: T['@type'], rowCount: number, typ } } +function lambdaColumn<T extends Column.Type>({ value, valueKind, rowCount, type }: Column.LambdaSpec<T>): Column<T['@type']> { + return { + '@type': type, + '@array': void 0, + isDefined: true, + rowCount, + value, + valueKind: valueKind ? valueKind : row => Column.ValueKind.Present, + toArray: params => { + const { array, start } = createArray(rowCount, params); + for (let i = 0, _i = array.length; i < _i; i++) array[i] = value(i + start); + return array; + }, + stringEquals: type.kind === 'str' + ? (row, v) => value(row) === v + : type.kind === 'float' || type.kind === 'int' + ? (row, v) => value(row) === +v + : (row, value) => false, + areValuesEqual: (rowA, rowB) => value(rowA) === value(rowB) + } +} + function arrayColumn<T extends Column.Type>({ array, type, valueKind }: Column.ArraySpec<T>): Column<T['@type']> { const rowCount = array.length; const value: Column<T['@type']>['value'] = type.kind === 'str' diff --git a/src/perf-tests/column.ts b/src/perf-tests/column.ts new file mode 100644 index 000000000..c5173a57b --- /dev/null +++ b/src/perf-tests/column.ts @@ -0,0 +1,78 @@ +import * as B from 'benchmark' +import C from '../mol-base/collections/column' + +export namespace Column { + function createData(n: number) { + const ret = new Float32Array(n); + for (let i = 0; i < n; i++) { + ret[i] = i * i + 1; + } + return ret; + } + + function raw(xs: ArrayLike<number>) { + let sum = 0; + for (let i = 0, _i = xs.length; i < _i; i++) { + sum += xs[i]; + } + return sum; + } + + function column(col: C<number>) { + let sum = 0; + for (let i = 0, _i = col.rowCount; i < _i; i++) { + sum += col.value(i); + } + return sum; + } + + function column1(col: C<number>) { + let sum = 0; + for (let i = 0, _i = col.rowCount; i < _i; i++) { + sum += col.value(i); + } + return sum; + } + + function val(i: number) { return i * i + 1; } + + export function runMono() { + const suite = new B.Suite(); + const data = createData(1000); + const nativeData = [...data as any]; + const col = C.ofArray({ array: data, type: C.Type.float }); + const lambda = C.ofLambda({ value: val, rowCount: data.length, type: C.Type.float }); + const cnst = C.ofConst(10, data.length, C.Type.float); + suite + .add('raw', () => raw(data)) + .add('native raw', () => raw(nativeData)) + .add('arraycol', () => column(col)) + .add('arraycol1', () => column(col)) + .add('const', () => column1(cnst)) + .add('arraycol2', () => column(col)) + .add('lambda', () => column1(lambda)) + .on('cycle', (e: any) => console.log(String(e.target))) + .run(); + } + + export function runPoly() { + const suite = new B.Suite(); + const data = createData(10000); + const nativeData = [...data as any]; + const col = C.ofArray({ array: data, type: C.Type.float }); + const lambda = C.ofLambda({ value: val, rowCount: data.length, type: C.Type.float }); + const cnst = C.ofConst(10, data.length, C.Type.float); + suite + .add('raw', () => raw(data)) + .add('native raw', () => raw(nativeData)) + .add('arraycol', () => column(col)) + .add('const', () => column(cnst)) + .add('arraycol2', () => column(col)) + .add('lambda', () => column(lambda)) + .on('cycle', (e: any) => console.log(String(e.target))) + .run(); + } +} + +Column.runMono(); +Column.runPoly(); \ No newline at end of file -- GitLab