From: Jérôme Benoit Date: Sat, 20 Apr 2024 15:02:13 +0000 (+0200) Subject: feat: add object hashing benchmarking X-Git-Url: https://git.piment-noir.org/?p=benchmarks-js.git;a=commitdiff_plain;h=bf2f087f3d30a4d8437a38b77cd0ae6f6f7da830 feat: add object hashing benchmarking Signed-off-by: Jérôme Benoit --- diff --git a/deep-clone-object.mjs b/deep-clone-object.mjs index 00753e2..40b508d 100644 --- a/deep-clone-object.mjs +++ b/deep-clone-object.mjs @@ -11,22 +11,22 @@ const object = generateRandomObject() group(`Deep clone object with ${Object.keys(object).length} keys`, () => { bench('JSON stringify/parse', (obj = object) => { - const objCloned = JSON.parse(JSON.stringify(obj)) + JSON.parse(JSON.stringify(obj)) }) bench('structuredClone', (obj = object) => { - const objCloned = structuredClone(obj) + structuredClone(obj) }) bench('lodash cloneDeep', (obj = object) => { - const objCloned = _.cloneDeep(obj) + _.cloneDeep(obj) }) bench('rambda clone', (obj = object) => { - const objCloned = rambdaClone(obj) + rambdaClone(obj) }) bench('just-clone', (obj = object) => { - const objCloned = clone(obj) + clone(obj) }) bench('deep-clone', (obj = object) => { - const objCloned = deepClone(obj) + deepClone(obj) }) }) diff --git a/deep-merge-object.mjs b/deep-merge-object.mjs index 50cc13c..a33dc21 100644 --- a/deep-merge-object.mjs +++ b/deep-merge-object.mjs @@ -15,13 +15,13 @@ group( } keys, object with ${Object.keys(objectToMerge).length} keys`, () => { bench('lodash merge', (obj = object) => { - const objMerged = _.merge(obj, objectToMerge) + _.merge(obj, objectToMerge) }) bench('rambda mergeDeepRight', (obj = object) => { - const objMerged = mergeDeepRight(obj, objectToMerge) + mergeDeepRight(obj, objectToMerge) }) bench('deepmerge', (obj = object) => { - const objMerged = deepMerge(obj, objectToMerge) + deepMerge(obj, objectToMerge) }) } ) diff --git a/is-empty-object.mjs b/is-empty-object.mjs index 2d78881..842ae4a 100644 --- a/is-empty-object.mjs +++ b/is-empty-object.mjs @@ -22,10 +22,10 @@ group(`Is empty object with ${Object.keys(object).length} keys`, () => { return obj?.constructor === Object && Object.keys(obj).length === 0 }) bench('lodash isEmpty', (obj = object) => { - return _.isEmpty(obj) + _.isEmpty(obj) }) bench('rambda isEmpty', (obj = object) => { - return isEmpty(obj) + isEmpty(obj) }) }) diff --git a/object-hash.mjs b/object-hash.mjs new file mode 100644 index 0000000..d20a317 --- /dev/null +++ b/object-hash.mjs @@ -0,0 +1,24 @@ +import hashObject from 'hash-object' +import { hasher } from 'node-object-hash' +import hash from 'object-hash' +import { bench, group, run } from 'tatami-ng' + +import { generateRandomObject } from './benchmark-utils.mjs' + +const object = generateRandomObject() + +group(`Hash object with ${Object.keys(object).length} keys`, () => { + bench('hash-object', (obj = object) => { + return hashObject(obj, { algorithm: 'sha256' }) + }) + bench('node-object-hash', (obj = object) => { + return hasher({ alg: 'sha256' }).hash(obj) + }) + bench('object-hash', (obj = object) => { + return hash(obj, { algorithm: 'sha256' }) + }) +}) + +await run({ + units: true +}) diff --git a/package.json b/package.json index fd29383..74cf327 100644 --- a/package.json +++ b/package.json @@ -37,14 +37,15 @@ "benchmark:busy-wait": "node busy-wait.mjs", "benchmark:deep-clone-object": "node deep-clone-object.mjs", "benchmark:deep-merge-object": "node deep-merge-object.mjs", - "benchmark:json-stringify": "node json-stringify.mjs", "benchmark:empty-array": "node empty-array.mjs", "benchmark:shallow-clone-object": "node shallow-clone-object.mjs", "benchmark:is-empty-object": "node is-empty-object.mjs", "benchmark:is-undefined": "node is-undefined.mjs", + "benchmark:json-stringify": "node json-stringify.mjs", "benchmark:quick-select": "node quick-select.mjs", "benchmark:max": "node max.mjs", "benchmark:min": "node min.mjs", + "benchmark:object-hash": "node object-hash.mjs", "benchmark:promise-handling": "node promise-handling.mjs", "benchmark:fibonacci": "node fibonacci.mjs", "benchmark:random": "node random.mjs", @@ -63,8 +64,11 @@ "dependencies": { "deep-clone": "^4.0.0", "deepmerge": "^4.3.1", + "hash-object": "^5.0.1", "just-clone": "^6.2.0", "lodash": "^4.17.21", + "node-object-hash": "^3.0.0", + "object-hash": "^3.0.0", "rambda": "^9.2.0", "tatami-ng": "^0.4.4", "uuid": "^9.0.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f24396..80aa405 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,12 +17,21 @@ importers: deepmerge: specifier: ^4.3.1 version: 4.3.1 + hash-object: + specifier: ^5.0.1 + version: 5.0.1 just-clone: specifier: ^6.2.0 version: 6.2.0 lodash: specifier: ^4.17.21 version: 4.17.21 + node-object-hash: + specifier: ^3.0.0 + version: 3.0.0 + object-hash: + specifier: ^3.0.0 + version: 3.0.0 rambda: specifier: ^9.2.0 version: 9.2.0 @@ -517,6 +526,10 @@ packages: supports-color: optional: true + decircular@0.1.1: + resolution: {integrity: sha512-V2Vy+QYSXdgxRPmOZKQWCDf1KQNTUP/Eqswv/3W20gz7+6GB1HTosNrWqK3PqstVpFw/Dd/cGTmXSTKPeOiGVg==} + engines: {node: '>=18'} + deep-clone@4.0.0: resolution: {integrity: sha512-bMvDVR8GiGCGHT4SgqXyXDD9Zmo3kv9YLq8aSO2xslP97A3mFkpNBg+t+fjXERvewzhmtk9efvL+V52iVkD0lg==} @@ -916,6 +929,10 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} + hash-object@5.0.1: + resolution: {integrity: sha512-iaRY4jYOow1caHkXW7wotYRjZDQk2nq4U7904anGJj8l4x1SLId+vuR8RpGoywZz9puD769hNFVFLFH9t+baJw==} + engines: {node: '>=18'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -1042,10 +1059,18 @@ packages: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} + is-obj@3.0.0: + resolution: {integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==} + engines: {node: '>=12'} + is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -1265,6 +1290,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-object-hash@3.0.0: + resolution: {integrity: sha512-jLF6tlyletktvSAawuPmH1SReP0YfZQ+tBrDiTCK+Ai7eXPMS9odi5xW/iKC7ZhrWJJ0Z5xYcW/x+1fVMn1Qvw==} + engines: {node: '>=16', pnpm: '>=8'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1273,6 +1302,10 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + object-inspect@1.13.1: resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} @@ -1540,6 +1573,10 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} + sort-keys@5.0.0: + resolution: {integrity: sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==} + engines: {node: '>=12'} + spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} @@ -1659,6 +1696,10 @@ packages: resolution: {integrity: sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==} engines: {node: '>=6'} + type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} + engines: {node: '>=16'} + typed-array-buffer@1.0.2: resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} engines: {node: '>= 0.4'} @@ -2264,6 +2305,8 @@ snapshots: dependencies: ms: 2.1.2 + decircular@0.1.1: {} + deep-clone@4.0.0: {} deep-is@0.1.4: {} @@ -2795,6 +2838,13 @@ snapshots: dependencies: has-symbols: 1.0.3 + hash-object@5.0.1: + dependencies: + decircular: 0.1.1 + is-obj: 3.0.0 + sort-keys: 5.0.0 + type-fest: 4.15.0 + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -2901,8 +2951,12 @@ snapshots: is-obj@2.0.0: {} + is-obj@3.0.0: {} + is-path-inside@3.0.3: {} + is-plain-obj@4.1.0: {} + is-regex@1.1.4: dependencies: call-bind: 1.0.7 @@ -3115,12 +3169,16 @@ snapshots: natural-compare@1.4.0: {} + node-object-hash@3.0.0: {} + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.1: {} object-keys@1.1.1: {} @@ -3391,6 +3449,10 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 + sort-keys@5.0.0: + dependencies: + is-plain-obj: 4.1.0 + spdx-exceptions@2.5.0: {} spdx-expression-parse@4.0.0: @@ -3529,6 +3591,8 @@ snapshots: type-fest@0.3.1: {} + type-fest@4.15.0: {} + typed-array-buffer@1.0.2: dependencies: call-bind: 1.0.7 diff --git a/shallow-clone-object.mjs b/shallow-clone-object.mjs index e01a3c4..f5c79c3 100644 --- a/shallow-clone-object.mjs +++ b/shallow-clone-object.mjs @@ -9,16 +9,16 @@ const object = generateRandomObject() group(`Shallow clone object with ${Object.keys(object).length} keys`, () => { bench('Spread', () => { - const objClone = { ...object } + return { ...object } }) bench('Object assign', () => { - const objClone = Object.assign({}, object) + return Object.assign({}, object) }) bench('lodash clone', () => { - const objClone = _.clone(object) + _.clone(object) }) bench('rambda assoc', () => { - const objClone = assoc(object) + assoc(object) }) })