add purely functional red-black tree benchmark
This commit is contained in:
parent
342d4b34ef
commit
c6c49a0966
3 changed files with 98 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/prompts": "^7.4.0"
|
"@inquirer/prompts": "^7.4.0",
|
||||||
|
"functional-red-black-tree": "^1.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
|
@ -11,6 +11,9 @@ importers:
|
||||||
'@inquirer/prompts':
|
'@inquirer/prompts':
|
||||||
specifier: ^7.4.0
|
specifier: ^7.4.0
|
||||||
version: 7.4.0
|
version: 7.4.0
|
||||||
|
functional-red-black-tree:
|
||||||
|
specifier: ^1.0.1
|
||||||
|
version: 1.0.1
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
|
|
@ -168,6 +171,9 @@ packages:
|
||||||
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
|
|
||||||
|
functional-red-black-tree@1.0.1:
|
||||||
|
resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==}
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
iconv-lite@0.4.24:
|
||||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
@ -335,6 +341,8 @@ snapshots:
|
||||||
iconv-lite: 0.4.24
|
iconv-lite: 0.4.24
|
||||||
tmp: 0.0.33
|
tmp: 0.0.33
|
||||||
|
|
||||||
|
functional-red-black-tree@1.0.1: {}
|
||||||
|
|
||||||
iconv-lite@0.4.24:
|
iconv-lite@0.4.24:
|
||||||
dependencies:
|
dependencies:
|
||||||
safer-buffer: 2.1.2
|
safer-buffer: 2.1.2
|
||||||
|
|
|
||||||
88
scripts/rbtree_bench.js
Normal file
88
scripts/rbtree_bench.js
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
import createTree from "functional-red-black-tree";
|
||||||
|
|
||||||
|
function benchmark(N) {
|
||||||
|
// fastest
|
||||||
|
function map() {
|
||||||
|
let t = new Map();
|
||||||
|
const startTime = Date.now();
|
||||||
|
for (let i=0; i<N; ++i) {
|
||||||
|
t.set(Math.random(), Math.random());
|
||||||
|
}
|
||||||
|
const endTime = Date.now();
|
||||||
|
return endTime - startTime;
|
||||||
|
}
|
||||||
|
const durInPlace = map();
|
||||||
|
console.log("in-place:", durInPlace, "ms");
|
||||||
|
|
||||||
|
// slower by constant factor
|
||||||
|
function fun() {
|
||||||
|
let t = createTree();
|
||||||
|
const startTime = Date.now();
|
||||||
|
for (let i=0; i<N; ++i) {
|
||||||
|
t = t.insert(Math.random(), Math.random());
|
||||||
|
}
|
||||||
|
const endTime = Date.now();
|
||||||
|
return endTime - startTime;
|
||||||
|
}
|
||||||
|
const durFunc = fun();
|
||||||
|
console.log("functional:", durFunc, "ms");
|
||||||
|
|
||||||
|
// a bit slower still
|
||||||
|
function funNoGC() {
|
||||||
|
const old = new Array(N);
|
||||||
|
let t = createTree();
|
||||||
|
const startTime = Date.now();
|
||||||
|
for (let i=0; i<N; ++i) {
|
||||||
|
old[i] = t; // prevent garbage collection
|
||||||
|
t = t.insert(Math.random(), Math.random());
|
||||||
|
}
|
||||||
|
const endTime = Date.now();
|
||||||
|
return endTime - startTime;
|
||||||
|
|
||||||
|
}
|
||||||
|
const durFuncNoGC = (N <= 1000000) ? funNoGC() : "";
|
||||||
|
console.log("functional (no GC):", durFuncNoGC, "ms");
|
||||||
|
|
||||||
|
// slowest (won't scale)
|
||||||
|
function copying() {
|
||||||
|
let t = new Map();
|
||||||
|
const startTime = Date.now();
|
||||||
|
for (let i=0; i<N; ++i) {
|
||||||
|
t = new Map(t);
|
||||||
|
t.set(Math.random(), Math.random());
|
||||||
|
}
|
||||||
|
const endTime = Date.now();
|
||||||
|
return endTime - startTime;
|
||||||
|
}
|
||||||
|
const durCopying = (N <= 20000) ? copying() : "";
|
||||||
|
console.log("copying:", durCopying, "ms");
|
||||||
|
|
||||||
|
// slower than slowest
|
||||||
|
function copyingNoGC() {
|
||||||
|
const old = new Array(N);
|
||||||
|
let t = new Map();
|
||||||
|
const startTime = Date.now();
|
||||||
|
for (let i=0; i<N; ++i) {
|
||||||
|
old[i] = t; // prevent garbage collection
|
||||||
|
t = new Map(t);
|
||||||
|
t.set(Math.random(), Math.random());
|
||||||
|
}
|
||||||
|
const endTime = Date.now();
|
||||||
|
return endTime - startTime;
|
||||||
|
}
|
||||||
|
const durCopyingNoGC = (N <= 10000) ? copyingNoGC() : "";
|
||||||
|
console.log("copying (no GC):", durCopyingNoGC, "ms");
|
||||||
|
|
||||||
|
return [N, durInPlace, durFunc, durFuncNoGC, durCopying, durCopyingNoGC];
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
for (const N of [100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000]) {
|
||||||
|
console.log("N =", N);
|
||||||
|
results.push(benchmark(N));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("N;in-place;functional;functional-NoGC;copying;copying-NoGC");
|
||||||
|
for (const [N, durInPlace, durFunc, durFuncNoGC, durCopying, durCopyingNoGC] of results) {
|
||||||
|
console.log(`${N};${durInPlace};${durFunc};${durFuncNoGC};${durCopying};${durCopyingNoGC}`);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue