diff --git a/benchmark/md4-cache.js b/benchmark/md4-cache.js new file mode 100644 index 000000000..00d02519d --- /dev/null +++ b/benchmark/md4-cache.js @@ -0,0 +1,39 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +const size = 50; + +const strings = []; +for (let count = 1; ; count *= 10) { + while (strings.length < count) { + const s = require("crypto").randomBytes(size).toString("hex"); + strings.push(s); + const hash = createHash("native-md4"); + hash.update(s); + hash.update(s); + hash.digest("hex"); + } + let i = 0; + console.log( + `${count} different 200 char strings: ` + + compare( + "native md4", + () => { + const hash = createHash("native-md4"); + const s = strings[(i = (i + 1) % strings.length)]; + hash.update(s); + hash.update(s); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + const s = strings[(i = (i + 1) % strings.length)]; + hash.update(s); + hash.update(s); + return hash.digest("hex"); + } + ) + ); +} diff --git a/benchmark/md4.js b/benchmark/md4.js index 64e1505eb..3b50d659c 100644 --- a/benchmark/md4.js +++ b/benchmark/md4.js @@ -1,61 +1,20 @@ -const crypto = require("crypto"); const createHash = require("../lib/util/createHash"); -let result; - -const measure = (fn, count) => { - const start = process.hrtime.bigint(); - for (let i = 0; i < count; i++) result = fn(); - return Number(process.hrtime.bigint() - start); -}; - -const NS_PER_MS = 1000000; // 1ms -const MIN_DURATION = 100 * NS_PER_MS; // 100ms -const MAX_DURATION = 1000 * NS_PER_MS; // 1000ms -const MAX_WARMUP_DURATION = 1 * NS_PER_MS; // 1ms - -const format = (fast, slow, fastName, slowName, count) => { - return `${fastName} is ${ - Math.round(((slow - fast) * 1000) / slow) / 10 - }% faster than ${slowName} (${Math.round(fast / 100 / count) / 10} µs vs ${ - Math.round(slow / 100 / count) / 10 - } µs, ${count}x)`; -}; - -const compare = (n1, f1, n2, f2) => { - let count = 1; - while (true) { - const timings = [f1, f2, f1, f2, f1, f2].map(f => measure(f, count)); - const t1 = Math.min(timings[0], timings[2], timings[4]); - const t2 = Math.min(timings[1], timings[3], timings[5]); - if (count === 1 && (t1 > MAX_WARMUP_DURATION || t2 > MAX_WARMUP_DURATION)) { - continue; - } - if ( - (t1 > MIN_DURATION && t2 > MIN_DURATION) || - t1 > MAX_DURATION || - t2 > MAX_DURATION - ) { - return t1 > t2 - ? format(t2, t1, n2, n1, count) - : format(t1, t2, n1, n2, count); - } - count *= 2; - } -}; +const compare = require("./micro-compare"); for (const size of [ - 1, 2, 4, 8, 10, 20, 40, 60, 80, 100, 200, 1000, 5000, 8183, 8184, 8185, 10000, - 20000, 32768, 32769, 50000, 100000, 200000, 500000 + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 ]) { const longString = require("crypto").randomBytes(size).toString("hex"); const buffer = require("crypto").randomBytes(size * 2); console.log( `string ${longString.length} chars: ` + compare( - "crypto md4", + "native md4", () => { - const hash = crypto.createHash("md4"); + const hash = createHash("native-md4"); + hash.update(longString); hash.update(longString); return hash.digest("hex"); }, @@ -63,6 +22,7 @@ for (const size of [ () => { const hash = createHash("md4"); hash.update(longString); + hash.update(longString); return hash.digest("hex"); } ) @@ -70,9 +30,10 @@ for (const size of [ console.log( `buffer ${buffer.length} bytes: ` + compare( - "crypto md4", + "native md4", () => { - const hash = crypto.createHash("md4"); + const hash = createHash("native-md4"); + hash.update(buffer); hash.update(buffer); return hash.digest("hex"); }, @@ -80,6 +41,7 @@ for (const size of [ () => { const hash = createHash("md4"); hash.update(buffer); + hash.update(buffer); return hash.digest("hex"); } ) diff --git a/benchmark/micro-compare.js b/benchmark/micro-compare.js new file mode 100644 index 000000000..fb4541bdd --- /dev/null +++ b/benchmark/micro-compare.js @@ -0,0 +1,44 @@ +let result; + +const measure = (fn, count) => { + const start = process.hrtime.bigint(); + for (let i = 0; i < count; i++) result = fn(); + return Number(process.hrtime.bigint() - start); +}; + +const NS_PER_MS = 1000000; // 1ms +const MIN_DURATION = 100 * NS_PER_MS; // 100ms +const MAX_DURATION = 1000 * NS_PER_MS; // 1000ms +const MAX_WARMUP_DURATION = 1 * NS_PER_MS; // 1ms + +const format = (fast, slow, fastName, slowName, count) => { + return `${fastName} is ${ + Math.round(((slow - fast) * 1000) / slow) / 10 + }% faster than ${slowName} (${Math.round(fast / 100 / count) / 10} µs vs ${ + Math.round(slow / 100 / count) / 10 + } µs, ${count}x)`; +}; + +const compare = (n1, f1, n2, f2) => { + let count = 1; + while (true) { + const timings = [f1, f2, f1, f2, f1, f2].map(f => measure(f, count)); + const t1 = Math.min(timings[0], timings[2], timings[4]); + const t2 = Math.min(timings[1], timings[3], timings[5]); + if (count === 1 && (t1 > MAX_WARMUP_DURATION || t2 > MAX_WARMUP_DURATION)) { + continue; + } + if ( + (t1 > MIN_DURATION && t2 > MIN_DURATION) || + t1 > MAX_DURATION || + t2 > MAX_DURATION + ) { + return t1 > t2 + ? format(t2, t1, n2, n1, count) + : format(t1, t2, n1, n2, count); + } + count *= 2; + } +}; + +module.exports = compare; diff --git a/benchmark/xxhash64-vs-md4.js b/benchmark/xxhash64-vs-md4.js new file mode 100644 index 000000000..0ed608559 --- /dev/null +++ b/benchmark/xxhash64-vs-md4.js @@ -0,0 +1,45 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +for (const size of [ + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 +]) { + const longString = require("crypto").randomBytes(size).toString("hex"); + const buffer = require("crypto").randomBytes(size * 2); + console.log( + `string ${longString.length} chars: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(longString); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(longString); + return hash.digest("hex"); + } + ) + ); + console.log( + `buffer ${buffer.length} bytes: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(buffer); + return hash.digest("hex"); + }, + "wasm md4", + () => { + const hash = createHash("md4"); + hash.update(buffer); + return hash.digest("hex"); + } + ) + ); +} diff --git a/benchmark/xxhash64.js b/benchmark/xxhash64.js new file mode 100644 index 000000000..7219b233e --- /dev/null +++ b/benchmark/xxhash64.js @@ -0,0 +1,49 @@ +const createHash = require("../lib/util/createHash"); + +const compare = require("./micro-compare"); + +for (const size of [ + 1, 10, 20, 40, 60, 80, 100, 200, 400, 1000, 1001, 5000, 8183, 8184, 8185, + 10000, 20000, 32768, 32769, 50000, 100000, 200000 +]) { + const longString = require("crypto").randomBytes(size).toString("hex"); + const buffer = require("crypto").randomBytes(size * 2); + console.log( + `string ${longString.length} chars: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + }, + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(longString); + hash.update(longString); + return hash.digest("hex"); + } + ) + ); + console.log( + `buffer ${buffer.length} bytes: ` + + compare( + "wasm xxhash64", + () => { + const hash = createHash("xxhash64"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + }, + "native md4", + () => { + const hash = createHash("native-md4"); + hash.update(buffer); + hash.update(buffer); + return hash.digest("hex"); + } + ) + ); +}