Skip to content
Snippets Groups Projects
Commit 1575e514 authored by David Sehnal's avatar David Sehnal
Browse files

perf tests

parent b6cf50da
No related branches found
No related tags found
No related merge requests found
...@@ -36,6 +36,11 @@ function setSearch(set: Set<number>, val: number) { ...@@ -36,6 +36,11 @@ function setSearch(set: Set<number>, val: number) {
return set.has(val); return set.has(val);
} }
type Mask = { min: number, max: number, mask: ArrayLike<number> }
function maskSearch({ min, max, mask }: Mask, val: number) {
return val >= min && val <= max && !!mask[val - min];
}
function prepare(list: ArrayLike<number>) { function prepare(list: ArrayLike<number>) {
const obj = Object.create(null), set = new Set<number>(); const obj = Object.create(null), set = new Set<number>();
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
...@@ -66,6 +71,22 @@ function prepareObj(list: ArrayLike<number>) { ...@@ -66,6 +71,22 @@ function prepareObj(list: ArrayLike<number>) {
return obj; return obj;
} }
function prepareMask(list: ArrayLike<number>): Mask {
let max = Number.NEGATIVE_INFINITY, min = Number.POSITIVE_INFINITY;
for (let i = 0; i < list.length; i++) {
const v = list[i];
if (max < v) max = v;
if (min > v) min = v;
}
const mask = new Uint8Array(max - min + 1);
for (let i = 0; i < list.length; i++) {
const v = list[i];
mask[v - min] = 1;
}
return { min, max, mask };
}
function testBinary(list: ArrayLike<number>, points: ArrayLike<number>) { function testBinary(list: ArrayLike<number>, points: ArrayLike<number>) {
let r = 0; let r = 0;
for (let i = 0, _i = points.length; i < _i; i++) { for (let i = 0, _i = points.length; i < _i; i++) {
...@@ -90,21 +111,33 @@ function testSet(set: Set<number>, points: ArrayLike<number>) { ...@@ -90,21 +111,33 @@ function testSet(set: Set<number>, points: ArrayLike<number>) {
return r; return r;
} }
function testMask(mask: Mask, points: ArrayLike<number>) {
let r = 0;
for (let i = 0, _i = points.length; i < _i; i++) {
if (maskSearch(mask, points[i])) r += points[i];
}
return r;
}
function run(f: () => number, n: number) { function run(f: () => number, n: number) {
for (let i = 0; i < n; i++) f(); for (let i = 0; i < n; i++) f();
} }
(function () { (function () {
const size = 100000; const size = 10000;
const list = createData(size); const list = createData(size);
const queryPoints = createData(size); const queryPoints = createData(size);
let obj = prepareObj(list); let obj = prepareObj(list);
let set = prepareSet(list); let set = prepareSet(list);
let mask = prepareMask(list);
console.log('list', testBinary(list, queryPoints)); console.log('list', testBinary(list, queryPoints));
console.log('obj', testObj(obj, queryPoints)); console.log('obj', testObj(obj, queryPoints));
console.log('set', testSet(set, queryPoints)); console.log('set', testSet(set, queryPoints));
console.log('mask', testMask(mask, queryPoints));
console.log('----------------------')
console.time('obj'); console.time('obj');
run(() => testObj(obj, queryPoints), 100); run(() => testObj(obj, queryPoints), 100);
...@@ -118,6 +151,12 @@ function run(f: () => number, n: number) { ...@@ -118,6 +151,12 @@ function run(f: () => number, n: number) {
run(() => testBinary(list, queryPoints), 100); run(() => testBinary(list, queryPoints), 100);
console.timeEnd('bin-search'); console.timeEnd('bin-search');
console.time('mask-search');
run(() => testMask(mask, queryPoints), 100);
console.timeEnd('mask-search');
console.log('----------------------')
console.time('prepare-obj'); console.time('prepare-obj');
run(() => prepareObj(list), 1); run(() => prepareObj(list), 1);
console.timeEnd('prepare-obj'); console.timeEnd('prepare-obj');
...@@ -125,4 +164,8 @@ function run(f: () => number, n: number) { ...@@ -125,4 +164,8 @@ function run(f: () => number, n: number) {
console.time('prepare-set'); console.time('prepare-set');
run(() => prepareSet(list).size, 1); run(() => prepareSet(list).size, 1);
console.timeEnd('prepare-set'); console.timeEnd('prepare-set');
console.time('prepare-mask');
run(() => prepareMask(list).min, 1);
console.timeEnd('prepare-mask');
}()) }())
...@@ -95,9 +95,9 @@ function heapSort(arr: number[]) { ...@@ -95,9 +95,9 @@ function heapSort(arr: number[]) {
} }
function createTestData(n: number) { function createTestData(n: number) {
const data = new Int32Array(n); //new Array(n); const data = []; //new Int32Array(n); //new Array(n);
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
data[i] = (n * Math.random());// | 0; data[i] = (n * Math.random()) | 0;
} }
return data; return data;
...@@ -142,6 +142,7 @@ function partition3(xs: number[], l: number, r: number) { ...@@ -142,6 +142,7 @@ function partition3(xs: number[], l: number, r: number) {
} }
function partition3_1(xs: number[], l: number, r: number) { function partition3_1(xs: number[], l: number, r: number) {
'use strict';
const v = medianPivot(xs, l, r); const v = medianPivot(xs, l, r);
// console.log('P', v); // console.log('P', v);
// console.log('I', xs.slice(l, r + 1)); // console.log('I', xs.slice(l, r + 1));
...@@ -170,6 +171,8 @@ function partition3_1(xs: number[], l: number, r: number) { ...@@ -170,6 +171,8 @@ function partition3_1(xs: number[], l: number, r: number) {
} }
function insertionSort(xs: number[], start: number, end: number) { function insertionSort(xs: number[], start: number, end: number) {
'use strict';
for (let i = start + 1; i <= end; i++) { for (let i = start + 1; i <= end; i++) {
const key = xs[i]; const key = xs[i];
let j = i - 1; let j = i - 1;
...@@ -182,6 +185,8 @@ function insertionSort(xs: number[], start: number, end: number) { ...@@ -182,6 +185,8 @@ function insertionSort(xs: number[], start: number, end: number) {
} }
function quickSort(xs: number[], low: number, high: number) { function quickSort(xs: number[], low: number, high: number) {
'use strict';
while (low < high) { while (low < high) {
if (high - low < 16) { if (high - low < 16) {
insertionSort(xs, low, high); insertionSort(xs, low, high);
...@@ -211,6 +216,97 @@ function checkSorted(arr: ArrayLike<number>) { ...@@ -211,6 +216,97 @@ function checkSorted(arr: ArrayLike<number>) {
console.log('sorted'); console.log('sorted');
} }
function defaultCmp(a: number, b: number) {
if (a > b) return 1
if (a < b) return -1
return 0
}
function quicksortCmp(arr: number[], cmp: any, bb: number, ee: number) {
cmp = cmp || defaultCmp
var begin = bb || 0
var end = (ee || arr.length) - 1
var stack = []
var sp = -1
var left = begin
var right = end
var tmp = 0.0
//var tmp2 = 0.0
// function swap(a: number, b: number) {
// tmp2 = arr[a]
// arr[a] = arr[b]
// arr[b] = tmp2
// }
var i, j
while (true) {
if (right - left <= 25) {
for (j = left + 1; j <= right; ++j) {
tmp = arr[j]
i = j - 1
while (i >= left && cmp(arr[i], tmp) > 0) {
arr[i + 1] = arr[i]
--i
}
arr[i + 1] = tmp
}
if (sp === -1) break
right = stack[sp--] // ?
left = stack[sp--]
} else {
var median = (left + right) >> 1
i = left + 1
j = right
swap(arr, median, i)
if (cmp(arr[left], arr[right]) > 0) {
swap(arr, left, right)
}
if (cmp(arr[i], arr[right]) > 0) {
swap(arr, i, right)
}
if (cmp(arr[left], arr[i]) > 0) {
swap(arr, left, i)
}
tmp = arr[i]
while (true) {
do i++; while (cmp(arr[i], tmp) < 0)
do j--; while (cmp(arr[j], tmp) > 0)
if (j < i) break
swap(arr, i, j)
}
arr[left + 1] = arr[j]
arr[j] = tmp
if (right - i + 1 >= j - left) {
stack[++sp] = i
stack[++sp] = right
right = j - 1
} else {
stack[++sp] = left
stack[++sp] = j - 1
left = i
}
}
}
return arr
}
(function test() { (function test() {
// console.log(medianPivot([1, 2, 3], 0, 2)) // console.log(medianPivot([1, 2, 3], 0, 2))
// console.log(medianPivot([1, 3, 2], 0, 2)) // console.log(medianPivot([1, 3, 2], 0, 2))
...@@ -219,7 +315,7 @@ function checkSorted(arr: ArrayLike<number>) { ...@@ -219,7 +315,7 @@ function checkSorted(arr: ArrayLike<number>) {
// console.log(medianPivot([2, 3, 1], 0, 2)) // console.log(medianPivot([2, 3, 1], 0, 2))
// console.log(medianPivot([3, 2, 1], 0, 2)) // console.log(medianPivot([3, 2, 1], 0, 2))
const n = 10000; const n = 1000;
Array.prototype.sort.call(createTestData(n), (a: number, b: number) => a - b); Array.prototype.sort.call(createTestData(n), (a: number, b: number) => a - b);
mergeSort(createTestData(n)); mergeSort(createTestData(n));
...@@ -231,6 +327,9 @@ function checkSorted(arr: ArrayLike<number>) { ...@@ -231,6 +327,9 @@ function checkSorted(arr: ArrayLike<number>) {
sd = createTestData(n); sd = createTestData(n);
quickSort(sd as any, 0, sd.length - 1); quickSort(sd as any, 0, sd.length - 1);
sd = createTestData(n);
quicksortCmp(sd as any, void 0, 0, sd.length - 1);
//console.log(sd); //console.log(sd);
// sd = createTestData(n); // sd = createTestData(n);
...@@ -268,7 +367,17 @@ function checkSorted(arr: ArrayLike<number>) { ...@@ -268,7 +367,17 @@ function checkSorted(arr: ArrayLike<number>) {
console.timeEnd('qs-sorted'); console.timeEnd('qs-sorted');
checkSorted(sd); checkSorted(sd);
const reverseSorted = new Int32Array(n); let reverseSorted = new Int32Array(n);
for (let i = 0; i < n; i++) {
reverseSorted[i] = sd[n - i - 1];
}
console.time('qs-reverse-sorted');
quickSort(reverseSorted as any, 0, reverseSorted.length - 1);
console.timeEnd('qs-reverse-sorted');
checkSorted(reverseSorted);
reverseSorted = new Int32Array(n);
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
reverseSorted[i] = sd[n - i - 1]; reverseSorted[i] = sd[n - i - 1];
} }
...@@ -278,10 +387,61 @@ function checkSorted(arr: ArrayLike<number>) { ...@@ -278,10 +387,61 @@ function checkSorted(arr: ArrayLike<number>) {
console.timeEnd('qs-reverse-sorted'); console.timeEnd('qs-reverse-sorted');
checkSorted(reverseSorted); checkSorted(reverseSorted);
sd = createTestData(n);
checkSorted(sd);
console.time('qs');
quickSort(sd as any, 0, sd.length - 1);
console.timeEnd('qs');
checkSorted(sd);
console.log('swap count', swapCount); console.log('swap count', swapCount);
console.log('--------------'); console.log('--------------');
//console.log('quick', sd);
sd = createTestData(n);
checkSorted(sd);
console.time('qs-a');
quicksortCmp(sd as any, void 0, 0, sd.length - 1);
console.timeEnd('qs-a');
checkSorted(sd);
console.time('qs-a-sorted');
quicksortCmp(sd as any, void 0, 0, sd.length - 1);
console.timeEnd('qs-a-sorted');
checkSorted(sd);
reverseSorted = new Int32Array(n);
for (let i = 0; i < n; i++) {
reverseSorted[i] = sd[n - i - 1];
}
console.time('qs-a-reverse-sorted');
quicksortCmp(reverseSorted as any, void 0, 0, reverseSorted.length - 1);
console.timeEnd('qs-a-reverse-sorted');
checkSorted(reverseSorted);
reverseSorted = new Int32Array(n);
for (let i = 0; i < n; i++) {
reverseSorted[i] = sd[n - i - 1];
}
console.time('qs-a-reverse-sorted');
quicksortCmp(reverseSorted as any, void 0, 0, reverseSorted.length - 1);
console.timeEnd('qs-a-reverse-sorted');
checkSorted(reverseSorted);
sd = createTestData(n);
checkSorted(sd);
console.time('qs-a');
quicksortCmp(sd as any, void 0, 0, sd.length - 1);
console.timeEnd('qs-a');
//console.log(sd);
checkSorted(sd);
console.log('--------------');
sd = createTestData(n); sd = createTestData(n);
checkSorted(sd); checkSorted(sd);
console.time('native'); console.time('native');
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment