Skip to content
Snippets Groups Projects
sort.ts 2.35 KiB
Newer Older
David Sehnal's avatar
David Sehnal committed
import * as B from 'benchmark'
David Sehnal's avatar
David Sehnal committed
import * as Sort from 'mol-data/util'
David Sehnal's avatar
David Sehnal committed

David Sehnal's avatar
David Sehnal committed
function shuffle(a: number[]) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        const t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    return a;
}

David Sehnal's avatar
David Sehnal committed
function createTestData(n: number) {
Alexander Rose's avatar
Alexander Rose committed
    const data = new Int32Array(n); // new Array(n);
David Sehnal's avatar
David Sehnal committed
    for (let i = 0; i < n; i++) {
David Sehnal's avatar
David Sehnal committed
        data[i] = i;
Alexander Rose's avatar
Alexander Rose committed
        // data[i] = (n * Math.random()) | 0;
David Sehnal's avatar
David Sehnal committed
    }
David Sehnal's avatar
David Sehnal committed
    shuffle(data as any);
David Sehnal's avatar
David Sehnal committed
    return data;
}

David Sehnal's avatar
David Sehnal committed
export function copyArray(xs: any) {
    const ret = new xs.constructor(xs.length);
    for (let i = 0, _i = xs.length; i < _i; i++) ret[i] = xs[i];
    return ret;
David Sehnal's avatar
David Sehnal committed
}

David Sehnal's avatar
David Sehnal committed
export function checkSorted(arr: ArrayLike<number>) {
David Sehnal's avatar
David Sehnal committed
    for (let i = 0; i < arr.length - 1; i++) {
        if (arr[i] > arr[i + 1]) {
David Sehnal's avatar
David Sehnal committed
            return false;
David Sehnal's avatar
David Sehnal committed
        }
    }
David Sehnal's avatar
David Sehnal committed
    return true;
David Sehnal's avatar
David Sehnal committed
}

David Sehnal's avatar
David Sehnal committed

David Sehnal's avatar
David Sehnal committed
export function runTest(size: number) {
    const _data = createTestData(size);

    const dataCopies: number[][] = [];
    let dataOffset = 0;
    function prepareData() {
        dataOffset = 0;
        for (let i = 0; i < 100; i++) {
            dataCopies[i] = copyArray(_data);
        }
    }

    function getData() {
        if (dataOffset < dataCopies.length) return dataCopies[dataOffset++];
        return copyArray(_data);
    }

    prepareData();

    const suite = new B.Suite();

David Sehnal's avatar
David Sehnal committed

David Sehnal's avatar
David Sehnal committed
    function le(x: number, y: number) { return x - y; }

    function name(n: string) { return `${n} (${size} elems)` }

    // TODO: the data copying skewes the benchmark -- write a simple benchmark util that allows for a preparation step.
    suite
        .add(name('native'), () => Array.prototype.sort.call(getData(), le))
        .add(name('qsort'), () => Sort.sortArray(getData()))
Alexander Rose's avatar
Alexander Rose committed
        // .add(name('qsort'), () => Sort.sort(getData(), 0, _data.length, Sort.arrayLess, Sort.arraySwap))
David Sehnal's avatar
David Sehnal committed
        .add(name('native sorted'), () => Array.prototype.sort.call(_data, le))
        .add(name('qsort sorted'), () => Sort.sortArray(_data))
Alexander Rose's avatar
Alexander Rose committed
        // .add(name('qsort sorted'), () => Sort.sort(_data, 0, _data.length, Sort.arrayLess, Sort.arraySwap))
David Sehnal's avatar
David Sehnal committed
        .on('cycle', (e: any) => {
            prepareData();
            console.log(String(e.target));
        })
        .run();
    console.log('---------------------');
}
David Sehnal's avatar
David Sehnal committed

Alexander Rose's avatar
Alexander Rose committed
// runTest(10);
// runTest(100);
// runTest(1000);
David Sehnal's avatar
David Sehnal committed
runTest(10000);
Alexander Rose's avatar
Alexander Rose committed
// runTest(100000);