UNPKG

@observ33r/object-equals

Version:

A fast, flexible and robust utility for deep equality comparison with type-specific logic and engine-aware design.

996 lines (806 loc) 213 kB
[![npm](https://img.shields.io/npm/v/@observ33r/object-equals.svg)](https://www.npmjs.com/package/@observ33r/object-equals) [![Size](https://badgen.net/bundlephobia/minzip/@observ33r/object-equals)](https://bundlephobia.com/package/@observ33r/object-equals) [![License](https://img.shields.io/npm/l/@observ33r/object-equals.svg)](https://github.com/observ33r/object-equals/blob/main/LICENSE) [![Donate](https://img.shields.io/badge/Donate-PayPal-ff69b4.svg)](https://www.paypal.com/donate/?hosted_button_id=PPPN7F3VXXE8W) # object-equals A fast, flexible and robust utility for deep equality comparison with type-specific logic and engine-aware design. ## Features - **High Performance** Outperforms popular libraries like `lodash.isEqual`, `fast-equals`, `dequal`, `are-deeply-equal` and `node.isDeepStrictEqual`. - **Engine-Aware Design** Tailored execution paths for V8 and JSC based runtimes to maximize performance. - **Web-First Architecture** Uses a lightweight, browser-safe implementation by default with full compatibility across all modern browsers and runtimes. - **Broad Support** Handles objects, arrays, sets, maps, array buffers, typed arrays, data views, booleans, strings, numbers, bigints, dates, errors, regular expressions and primitives. - **Customizable** Fine-tune behavior with options for handling circular references, cross-realm objects, react elements and more. - **Fully Tested** Includes over 40 unit tests with complete parity against `lodash.isEqual` and edge case coverage. - **Type-Safe** Fully typed with TypeScript declarations. ## Installation ```bash npm install @observ33r/object-equals ``` ## Usage ### `objectEquals(target, source, [options])` Compares two values for deep equality. - **target**: The first value to compare (`unknown`). - **source**: The second value to compare (`unknown`). - **options**: Optional configuration object (see below). - **Returns**: `boolean` - `true` if values are deeply equal, `false` otherwise. - **Throws**: `TypeError` if an unsupported object type is encountered. #### Options | Property | Type | Default | Description | | :---: | :---: | :---: | :--- | | circular | `boolean` | `false` | Enables circular reference handling using a cache | | crossrealm | `boolean` | `false` | Enables cross-realm object comparison (e.g., vm contexts) | | react | `boolean` | `false` | Enables React element comparison (checks `$$typeof`, `type`, `key`, `ref` and `props`) | | symbols | `boolean` | `false` | Includes symbol-keyed properties in object comparison | | fallback | `boolean` | `false` | Enables fallback comparison using `valueOf()` or `toString()` | | cache | `Map \| WeakMap` | `undefined` | Custom cache for circular references (auto-managed if `circular` is `true`) | or ### `objectEqualsCore(target, source, circular, crossrealm, react, symbols, fallback, cache)` The core comparison function, exposed for advanced use cases. Takes individual parameters instead of an options object. ## Examples ### Basic ```javascript import { objectEquals } from '@observ33r/object-equals'; const obj1 = { a: 1, b: [2, 3] }; const obj2 = { a: 1, b: [2, 3] }; console.log(objectEquals(obj1, obj2)); //true ``` ### Extended objects ```javascript import { objectEquals } from '@observ33r/object-equals'; class ExtendedMap extends Map {} const map1 = new ExtendedMap([['key-1', 'value-1']]); const map2 = new ExtendedMap([['key-1', 'value-1']]); console.log(objectEquals(map1, map2)); //true ``` ### Circular objects ```javascript import { objectEquals } from '@observ33r/object-equals'; const obj1 = { a: 1 }; obj1.self = obj1; const obj2 = { a: 1 }; obj2.self = obj2; console.log(objectEquals(obj1, obj2, { circular: true })); //true ``` ### Cross-Realm objects ```javascript import vm from 'node:vm'; import { objectEquals } from '@observ33r/object-equals'; class ExtendedArray extends Array {} const CrossRealmArray = vm.runInContext('Array', vm.createContext()); const array = [1, 2, 3]; const extArr = new ExtendedArray(1, 2, 3); const realmArr = new CrossRealmArray(1, 2, 3); //extended console.log(objectEquals(array, extArr, { crossrealm: true })); //true //vm context console.log(objectEquals(array, realmArr, { crossrealm: true })); //true ``` ### React elements ```javascript import { createElement } from 'react'; import { objectEquals } from '@observ33r/object-equals'; const el1 = createElement('a', { onClick: () => { console.log('click'); } }, 'text'); const el2 = createElement('a', { onClick: () => { console.log('click'); } }, 'text'); console.log(objectEquals(el1, el2, { react: true })); //true ``` ### Symbol keys ```javascript import { objectEquals } from '@observ33r/object-equals'; const obj1 = { a: 1, [Symbol('b')]: [2, 3] }; const obj2 = { a: 1, [Symbol('b')]: [2, 3] }; console.log(objectEquals(obj1, obj2, { symbols: true })); //true ``` ### Catch unsupported types with fallback option ```javascript import { objectEquals } from '@observ33r/object-equals'; const params1 = new URLSearchParams('foo=1&bar=2'); const params2 = new URLSearchParams('foo=1&bar=2'); console.log(objectEquals(params1, params2, { fallback: true })); //true ``` ## Basic benchmark ### Big JSON Object (~1.2 MiB, deeply nested) | Library | Time | Relative Speed | | :--- | :--- | :--- | | object-equals | 483.52 µs | 1.00x (baseline) | | fast-equals | 1.37 ms | 2.83x slower | | dequal | 1.44 ms | 2.98x slower | | node.isDeepStrictEqual | 2.43 ms | 5.02x slower | | are-deeply-equal | 2.76 ms | 5.70x slower | | lodash.isEqual | 5.23 ms | 10.81x slower | <details> <summary>Full benchmark result with hardware counters</summary> ```console clk: ~3.70 GHz cpu: AMD Ryzen 5 3600 6-Core Processor runtime: node 24.1.0 (x64-linux) benchmark avg (min … max) p75 / p99 (min … top 1%) ------------------------------------------- ------------------------------- • Big JSON Object (~1.2 MiB, deeply nested) ------------------------------------------- ------------------------------- object-equals 483.52 µs/iter 484.03 µs █ (466.96 µs … 704.74 µs) 664.33 µs █▅ (340.07 kb … 1.44 mb) 968.34 kb ▃██▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 3.12 ipc ( 87.00% cache) 4.94k branch misses 1.98M cycles 6.17M instructions 114.31k c-refs 14.86k c-misses are-deeply-equal 2.76 ms/iter 2.79 ms █ (2.58 ms … 3.84 ms) 3.60 ms █ ▄ (920.88 kb … 2.17 mb) 1.78 mb ▄█▃██▃▂▃▄▃▂▁▁▂▁▁▁▁▁▁▁ 2.51 ipc ( 88.60% cache) 26.89k branch misses 10.31M cycles 25.86M instructions 357.36k c-refs 40.75k c-misses fast-equals 1.37 ms/iter 1.37 ms █▃ (1.33 ms … 1.71 ms) 1.60 ms ██ (806.30 kb … 1.15 mb) 968.52 kb ▅███▇▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.73 ipc ( 87.44% cache) 12.87k branch misses 5.26M cycles 14.35M instructions 124.59k c-refs 15.65k c-misses dequal 1.44 ms/iter 1.49 ms ▂█ (1.38 ms … 1.66 ms) 1.55 ms ██▃ ▂▂ (484.92 kb … 776.80 kb) 485.59 kb ▃████▄▅▂▃▄▃▄███▅▃▂▂▂▁ 2.56 ipc ( 90.46% cache) 11.93k branch misses 5.77M cycles 14.77M instructions 121.39k c-refs 11.59k c-misses lodash.isEqual 5.23 ms/iter 5.23 ms █▄ (5.14 ms … 5.98 ms) 5.65 ms ███▃ ( 2.31 mb … 4.32 mb) 2.97 mb ▅████▂▄▃▂▂▂▂▁▂▂▁▁▁▁▁▂ 2.57 ipc ( 96.64% cache) 37.07k branch misses 21.43M cycles 55.03M instructions 822.59k c-refs 27.62k c-misses node.isDeepStrictEqual 2.43 ms/iter 2.43 ms █ (2.38 ms … 2.95 ms) 2.74 ms ▇█▄ (280.57 kb … 2.07 mb) 1.36 mb ▆███▄▂▁▁▁▁▁▁▁▂▂▁▁▁▁▁▁ 2.62 ipc ( 92.07% cache) 16.58k branch misses 9.92M cycles 26.02M instructions 189.42k c-refs 15.03k c-misses summary object-equals 2.83x faster than fast-equals 2.98x faster than dequal 5.02x faster than node.isDeepStrictEqual 5.7x faster than are-deeply-equal 10.81x faster than lodash.isEqual ``` </details> > [!NOTE] > The object is a deeply nested structure (depth: 17) containing objects, arrays, strings, booleans, numbers and nulls. It has a file size of 1.2 MiB, with a root size of 18 and nested sizes ranging from 0 to 21. ## React and Advanced benchmark > [!IMPORTANT] > Times for object sizes: 16, 512, 4096, 16386 ### React elements | Library | 16 | 512 | 4096 | 16386 | Speed Range | | :--- | :--- | :--- | :--- | :--- | :--- | | object-equals | 996.75 ns | 30.33 µs | 267.94 µs | 1.07 ms | 1.00x (baseline) | | react-fast-compare | 6.87 µs | 210.55 µs | 1.63 ms | 6.66 ms | 6.89x-6.22x slower | | fast-equals | 7.02 µs | 208.94 µs | 1.58 ms | 6.83 ms | 7.05x-6.38x slower | | dequal | 7.96 µs | 240.44 µs | 1.96 ms | 7.70 ms | 7.99x-7.19x slower | | are-deeply-equal | 16.93 µs | 510.79 µs | 4.27 ms | 19.10 ms | 16.99x-17.84x slower | | node.isDeepStrictEqual | 17.01 µs | 473.63 µs | 4.01 ms | 15.77 ms | 17.06x-14.73x slower | | lodash.isEqual | 34.82 µs | 1.03 ms | 8.01 ms | 31.12 ms | 34.93x-29.07x slower | <details> <summary>Full benchmark results with hardware counters</summary> ```console clk: ~3.79 GHz cpu: AMD Ryzen 5 3600 6-Core Processor runtime: node 24.1.0 (x64-linux) benchmark avg (min … max) p75 / p99 (min … top 1%) ------------------------------------------- ------------------------------- • React elements [size=16] ------------------------------------------- ------------------------------- object-equals 996.75 ns/iter 1.02 µs █ (928.56 ns … 1.20 µs) 1.19 µs ▃▂█▃ ( 1.87 kb … 2.44 kb) 2.13 kb ██████▆▅▂▄▃▃▃▃▂▂▃▄▂▂▂ 3.87 ipc ( 96.36% cache) 1.10 branch misses 3.91k cycles 15.13k instructions 91.50 c-refs 3.33 c-misses react-fast-compare 6.87 µs/iter 6.91 µs █ █ (6.77 µs … 7.02 µs) 6.96 µs █ █ █ █ ( 6.37 kb … 6.38 kb) 6.38 kb █▁▁████▁█▁███▁██▁▁███ 3.09 ipc ( 96.77% cache) 2.53 branch misses 26.41k cycles 81.69k instructions 398.22 c-refs 12.86 c-misses are-deeply-equal 16.93 µs/iter 17.20 µs █ (16.58 µs … 17.23 µs) 17.22 µs █ █ ( 13.20 kb … 13.20 kb) 13.20 kb █▁█▁▁██▁██▁▁█▁▁▁▁▁▁▁█ 2.74 ipc ( 95.85% cache) 61.43 branch misses 64.91k cycles 178.00k instructions 836.31 c-refs 34.69 c-misses fast-equals 7.02 µs/iter 7.13 µs ▂ █ (6.75 µs … 7.24 µs) 7.21 µs █ █ ▅ ▅ ▅ ( 6.37 kb … 6.38 kb) 6.38 kb ▇▁▁▁▁█▁▇▁▇▇█▇█▁▁█▇▇▁█ 2.98 ipc ( 95.84% cache) 2.72 branch misses 26.95k cycles 80.19k instructions 336.77 c-refs 14.01 c-misses dequal 7.96 µs/iter 7.98 µs ██ █ (7.90 µs … 8.16 µs) 8.04 µs ▅██▅▅ █▅▅ ▅▅ ▅ ▅ ▅▅ ( 3.17 kb … 3.20 kb) 3.19 kb █████▁███▁██▁█▁█▁▁▁██ 2.82 ipc ( 96.04% cache) 2.45 branch misses 30.68k cycles 86.39k instructions 207.30 c-refs 8.22 c-misses lodash.isEqual 34.82 µs/iter 34.22 µs █ (33.14 µs … 301.34 µs) 47.00 µs █ (520.00 b … 903.28 kb) 23.84 kb ▁█▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.56 ipc ( 99.03% cache) 42.48 branch misses 135.39k cycles 346.90k instructions 6.80k c-refs 65.59 c-misses node.isDeepStrictEqual 17.01 µs/iter 16.68 µs █ (16.33 µs … 224.45 µs) 23.24 µs ▇█ ( 2.02 kb … 267.35 kb) 10.23 kb ██▃▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.68 ipc ( 98.52% cache) 51.84 branch misses 66.51k cycles 178.50k instructions 1.38k c-refs 20.41 c-misses summary object-equals 6.89x faster than react-fast-compare 7.05x faster than fast-equals 7.99x faster than dequal 16.99x faster than are-deeply-equal 17.06x faster than node.isDeepStrictEqual 34.93x faster than lodash.isEqual • React elements [size=512] ------------------------------------------- ------------------------------- object-equals 30.33 µs/iter 30.67 µs █ (29.65 µs … 31.49 µs) 31.41 µs █ █ (144.19 b … 149.53 b) 144.64 b ██▁██▁▁▁▁▁█▁█▁▁▁█▁▁▁█ 3.73 ipc ( 90.22% cache) 5.06 branch misses 121.14k cycles 452.06k instructions 9.09k c-refs 888.87 c-misses react-fast-compare 210.55 µs/iter 210.22 µs ▃█ (198.47 µs … 437.07 µs) 254.83 µs ██▃ ( 78.10 kb … 562.63 kb) 193.32 kb ▁████▇▄▂▂▁▁▁▁▁▂▂▂▁▁▁▁ 3.06 ipc ( 75.89% cache) 43.86 branch misses 803.58k cycles 2.46M instructions 18.31k c-refs 4.41k c-misses are-deeply-equal 510.79 µs/iter 512.35 µs █ (485.49 µs … 743.90 µs) 637.30 µs ▆█▃ (297.80 kb … 590.24 kb) 409.69 kb ▁▃███▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.72 ipc ( 84.37% cache) 2.06k branch misses 1.97M cycles 5.35M instructions 37.94k c-refs 5.93k c-misses fast-equals 208.94 µs/iter 209.11 µs █▆ (189.51 µs … 533.05 µs) 281.53 µs ▇██ ( 49.34 kb … 416.51 kb) 193.08 kb ▂▄████▄▂▁▁▁▂▂▂▁▁▁▁▁▁▁ 3.02 ipc ( 74.06% cache) 45.21 branch misses 799.09k cycles 2.41M instructions 15.51k c-refs 4.02k c-misses dequal 240.44 µs/iter 240.90 µs █▆ (218.76 µs … 473.41 µs) 313.99 µs ██ ( 76.81 kb … 313.82 kb) 96.95 kb ▃▅▆███▅▂▂▁▃▂▂▂▂▁▁▁▁▁▁ 2.82 ipc ( 73.38% cache) 43.71 branch misses 924.49k cycles 2.60M instructions 12.90k c-refs 3.44k c-misses lodash.isEqual 1.03 ms/iter 1.02 ms █ (972.24 µs … 2.94 ms) 1.31 ms █ (308.13 kb … 1.23 mb) 665.75 kb ▁██▇▄▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁ 2.60 ipc ( 95.26% cache) 170.73 branch misses 3.96M cycles 10.31M instructions 144.13k c-refs 6.83k c-misses node.isDeepStrictEqual 473.63 µs/iter 474.91 µs █▃ (455.86 µs … 708.57 µs) 568.64 µs ▅██ (241.80 kb … 337.87 kb) 288.69 kb ▂████▄▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.74 ipc ( 75.65% cache) 687.57 branch misses 1.93M cycles 5.28M instructions 22.09k c-refs 5.38k c-misses summary object-equals 6.89x faster than fast-equals 6.94x faster than react-fast-compare 7.93x faster than dequal 15.62x faster than node.isDeepStrictEqual 16.84x faster than are-deeply-equal 33.93x faster than lodash.isEqual • React elements [size=4096] ------------------------------------------- ------------------------------- object-equals 267.94 µs/iter 265.96 µs █ (248.63 µs … 518.86 µs) 443.63 µs ▅█ ( 84.75 kb … 832.33 kb) 512.48 kb ██▇▃▃▃▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁ 3.60 ipc ( 86.60% cache) 182.06 branch misses 1.01M cycles 3.64M instructions 99.87k c-refs 13.38k c-misses react-fast-compare 1.63 ms/iter 1.65 ms ▃█▅ (1.52 ms … 1.97 ms) 1.88 ms ███▇ ( 1.50 mb … 1.50 mb) 1.50 mb ▂▅▂█████▇▅▅▃▂▂▁▂▂▂▂▁▁ 3.13 ipc ( 95.93% cache) 133.97 branch misses 6.28M cycles 19.68M instructions 147.83k c-refs 6.02k c-misses are-deeply-equal 4.27 ms/iter 4.27 ms █ (4.12 ms … 5.97 ms) 5.94 ms ▇█▂ ( 2.66 mb … 3.22 mb) 3.15 mb ███▄▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.69 ipc ( 91.36% cache) 15.95k branch misses 15.89M cycles 42.74M instructions 403.17k c-refs 34.85k c-misses fast-equals 1.58 ms/iter 1.59 ms █▂ (1.51 ms … 1.80 ms) 1.77 ms ▅███▂ ( 1.50 mb … 1.50 mb) 1.50 mb ▂▅█████▆▃▃▃▄▃▁▂▁▁▁▂▂▁ 3.01 ipc ( 93.59% cache) 134.86 branch misses 6.42M cycles 19.30M instructions 134.11k c-refs 8.60k c-misses dequal 1.96 ms/iter 1.96 ms █▇ (1.86 ms … 2.48 ms) 2.34 ms ██▃ (768.33 kb … 769.59 kb) 768.36 kb ▇███▆▃▂▄▃▃▃▃▂▁▁▂▂▂▁▁▁ 2.82 ipc ( 91.61% cache) 120.87 branch misses 7.38M cycles 20.81M instructions 108.17k c-refs 9.08k c-misses lodash.isEqual 8.01 ms/iter 8.08 ms █▂ (7.87 ms … 8.50 ms) 8.34 ms ▅██▇ ▄ ▄ ( 4.39 mb … 5.96 mb) 5.15 mb ▇██████▄▃▃▃▄█▃▃▆▃▄▁▃▃ 2.65 ipc ( 98.46% cache) 918.98 branch misses 30.85M cycles 81.87M instructions 1.18M c-refs 18.19k c-misses node.isDeepStrictEqual 4.01 ms/iter 4.02 ms ▂█▆ (3.92 ms … 4.31 ms) 4.26 ms ▆▃███▇ ( 2.25 mb … 2.25 mb) 2.25 mb ▅███████▅▂▂▂▁▂▂▂▁▂▂▂▂ 2.74 ipc ( 95.03% cache) 5.27k branch misses 15.40M cycles 42.14M instructions 181.32k c-refs 9.01k c-misses summary object-equals 5.89x faster than fast-equals 6.09x faster than react-fast-compare 7.3x faster than dequal 14.95x faster than node.isDeepStrictEqual 15.93x faster than are-deeply-equal 29.9x faster than lodash.isEqual • React elements [size=16386] ------------------------------------------- ------------------------------- object-equals 1.07 ms/iter 1.08 ms █▇ (990.79 µs … 1.47 ms) 1.40 ms ██▆ ( 1.89 mb … 2.11 mb) 2.00 mb ▄████▅▄▄▄▃▂▄▂▁▂▁▁▁▁▁▁ 3.56 ipc ( 94.14% cache) 1.17k branch misses 4.10M cycles 14.59M instructions 432.17k c-refs 25.33k c-misses react-fast-compare 6.66 ms/iter 6.71 ms █ ▆ █▃ (6.49 ms … 7.15 ms) 7.05 ms █▅█▅██▄▇ ▂ ( 6.00 mb … 6.00 mb) 6.00 mb █████████▆█▅█▁▁▃█▁▁▁▃ 3.08 ipc ( 95.26% cache) 398.43 branch misses 25.58M cycles 78.71M instructions 637.63k c-refs 30.24k c-misses are-deeply-equal 19.10 ms/iter 19.02 ms █ (18.64 ms … 21.26 ms) 21.16 ms ██▃ ( 12.50 mb … 12.58 mb) 12.53 mb ▇███▇▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▅ 2.55 ipc ( 86.82% cache) 64.57k branch misses 67.04M cycles 171.26M instructions 1.77M c-refs 233.77k c-misses fast-equals 6.83 ms/iter 6.96 ms ▅▃█▃██ (6.56 ms … 7.25 ms) 7.21 ms ▃██████▃ ▆▆▃▆ ▃▃ ( 6.00 mb … 6.00 mb) 6.00 mb ▆█████████████████▄▄▆ 2.95 ipc ( 94.28% cache) 469.05 branch misses 26.19M cycles 77.22M instructions 534.64k c-refs 30.56k c-misses dequal 7.70 ms/iter 7.75 ms █▅▃ (7.50 ms … 8.26 ms) 8.20 ms ▅███▄▂ ( 3.00 mb … 3.00 mb) 3.00 mb ▆██████▆▆▆▁▁▄▄▃▃▃▇▁▄▃ 2.81 ipc ( 93.81% cache) 332.51 branch misses 29.62M cycles 83.26M instructions 437.01k c-refs 27.03k c-misses lodash.isEqual 31.12 ms/iter 31.27 ms █ █ █ █ █ (30.74 ms … 31.55 ms) 31.45 ms ▅▅ ▅ █▅█▅ █ ▅█▅█ ▅ ( 20.63 mb … 20.93 mb) 20.65 mb ██▁█▁████▁▁█▁▁████▁▁█ 2.58 ipc ( 98.47% cache) 5.71k branch misses 127.70M cycles 329.50M instructions 5.62M c-refs 85.88k c-misses node.isDeepStrictEqual 15.77 ms/iter 16.24 ms ▅█▂ (14.98 ms … 17.70 ms) 17.61 ms ███▅ ▂ ( 9.00 mb … 9.00 mb) 9.00 mb ████▇▁▄▁▄▄▄▁▁▇▁▄▁█▁▄▇ 2.73 ipc ( 95.00% cache) 19.27k branch misses 61.85M cycles 168.58M instructions 733.94k c-refs 36.68k c-misses summary object-equals 6.22x faster than react-fast-compare 6.38x faster than fast-equals 7.19x faster than dequal 14.73x faster than node.isDeepStrictEqual 17.84x faster than are-deeply-equal 29.07x faster than lodash.isEqual ``` </details> > [!NOTE] > The `react` option is designed to support React elements comparison, including props that contain inline functions (e.g. `onClick: () => ...`). Most libraries fail such comparisons due to referential inequality. For benchmarking fairness, all comparisons use structurally equivalent trees without inline functions. ### Object with mixed primitive values | Library | 16 | 512 | 4096 | 16386 | Speed Range | | :--- | :--- | :--- | :--- | :--- | :--- | | object-equals | 142.36 ns | 31.99 µs | 694.95 µs | 3.91 ms | 1.00x (baseline) | | fast-equals | 873.33 ns | 38.59 µs | 792.80 µs | 4.12 ms | 6.13x-1.06x slower | | are-deeply-equal | 899.22 ns | 37.54 µs | 780.04 µs | 4.39 ms | 6.32x-1.12x slower | | dequal | 929.12 ns | 63.33 µs | 946.56 µs | 4.77 ms | 6.53x-1.22x slower | | node.isDeepStrictEqual | 937.36 ns | 37.97 µs | 747.63 µs | 4.32 ms | 6.58x-1.11x slower | | lodash.isEqual | 1.29 µs | 43.88 µs | 842.46 µs | 4.48 ms | 9.08x-1.15x slower | <details> <summary>Full benchmark results with hardware counters</summary> ```console clk: ~3.91 GHz cpu: AMD Ryzen 5 3600 6-Core Processor runtime: node 24.1.0 (x64-linux) benchmark avg (min … max) p75 / p99 (min … top 1%) ------------------------------------------- ------------------------------- • Object with mixed primitive values [size=16] ------------------------------------------- ------------------------------- object-equals 142.36 ns/iter 142.02 ns █ (136.68 ns … 223.73 ns) 188.70 ns █▅ (197.47 b … 456.27 b) 352.22 b ▅██▅▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁ 4.03 ipc ( 96.60% cache) 0.03 branch misses 578.44 cycles 2.33k instructions 11.72 c-refs 0.40 c-misses are-deeply-equal 899.22 ns/iter 916.66 ns █ (847.15 ns … 1.10 µs) 1.06 µs █▄ (430.28 b … 761.70 b) 600.25 b ███▅▆▃▄▃▃▃▂▃▃▂▂▂▂▂▃▃▁ 2.80 ipc ( 95.75% cache) 0.06 branch misses 3.54k cycles 9.90k instructions 25.78 c-refs 1.10 c-misses fast-equals 873.33 ns/iter 892.94 ns ▆▅ ▆█▆▂ (807.30 ns … 1.12 µs) 1.03 µs ▂██ █████▄ ( 16.11 b … 557.93 b) 352.14 b ██████████▃▄▄▄▆▃▃▁▁▃▃ 2.83 ipc ( 94.86% cache) 0.05 branch misses 3.40k cycles 9.64k instructions 12.67 c-refs 0.65 c-misses dequal 929.12 ns/iter 935.21 ns ▂█ (903.99 ns … 1.04 µs) 1.03 µs ██▅ (170.30 b … 404.96 b) 177.39 b ▅███▇▅▅▅▃▄▂▂▂▁▁▁▁▁▁▁▂ 2.75 ipc ( 93.86% cache) 0.04 branch misses 3.57k cycles 9.82k instructions 6.64 c-refs 0.41 c-misses lodash.isEqual 1.29 µs/iter 1.31 µs █ (1.22 µs … 1.50 µs) 1.39 µs ██ (687.52 b … 1.33 kb) 933.00 b ▆▇▄▃▂▄▂▅▆██▃▁▂▁▃▂▃▁▃▂ 2.72 ipc ( 96.96% cache) 0.10 branch misses 5.07k cycles 13.78k instructions 85.48 c-refs 2.60 c-misses node.isDeepStrictEqual 937.36 ns/iter 940.00 ns █ (850.00 ns … 194.47 µs) 1.33 µs █ ▆█ (792.00 b … 411.47 kb) 813.54 b ▂████▄▂▂▂▁▂▁▁▁▁▁▁▁▁▁▁ 2.11 ipc ( 99.63% cache) 30.08 branch misses 5.07k cycles 10.69k instructions 449.28 c-refs 1.68 c-misses summary object-equals 6.13x faster than fast-equals 6.32x faster than are-deeply-equal 6.53x faster than dequal 6.58x faster than node.isDeepStrictEqual 9.08x faster than lodash.isEqual • Object with mixed primitive values [size=512] ------------------------------------------- ------------------------------- object-equals 31.99 µs/iter 32.04 µs █ (30.57 µs … 33.99 µs) 33.78 µs █ █ █ (259.87 b … 261.79 b) 260.07 b █▁██▁▁▁███▁▁▁▁▁▁▁▁▁▁█ 3.60 ipc ( 98.97% cache) 186.76 branch misses 124.97k cycles 449.46k instructions 10.39k c-refs 106.56 c-misses are-deeply-equal 37.54 µs/iter 38.29 µs █ (36.45 µs … 39.97 µs) 39.51 µs ▅ █ ( 8.78 kb … 8.78 kb) 8.78 kb █▇█▁▇▁▁▁▁▁▁▁▇▁▁▁▇▁▁▁▇ 3.48 ipc ( 98.95% cache) 183.79 branch misses 149.81k cycles 521.40k instructions 12.67k c-refs 133.02 c-misses fast-equals 38.59 µs/iter 38.62 µs █ (38.20 µs … 39.12 µs) 39.09 µs █ (259.87 b … 260.79 b) 259.95 b ▇▇▇▇▁▁▁▇▁█▁▁▁▇▁▁▁▁▁▁▇ 3.53 ipc ( 98.98% cache) 233.07 branch misses 156.17k cycles 551.76k instructions 10.13k c-refs 103.53 c-misses dequal 63.33 µs/iter 63.42 µs █ (56.82 µs … 227.68 µs) 100.35 µs █ (416.00 b … 202.04 kb) 17.11 kb ▂█▅▅▂▂▁▃▃▂▁▁▁▁▁▁▁▁▁▁▁ 2.92 ipc ( 97.68% cache) 628.84 branch misses 248.85k cycles 726.95k instructions 10.27k c-refs 238.13 c-misses lodash.isEqual 43.88 µs/iter 43.65 µs █ (40.66 µs … 254.68 µs) 63.63 µs █▇ (840.00 b … 223.34 kb) 25.82 kb ▃███▂▂▂▂▂▁▁▂▁▁▁▁▁▁▁▁▁ 3.36 ipc ( 97.79% cache) 383.74 branch misses 168.88k cycles 567.55k instructions 14.22k c-refs 314.29 c-misses node.isDeepStrictEqual 37.97 µs/iter 38.11 µs █ (37.18 µs … 39.98 µs) 38.98 µs █ █ ( 8.38 kb … 8.38 kb) 8.38 kb █▁▁████▁▁▁█▁█▁▁▁▁▁▁▁█ 3.56 ipc ( 98.64% cache) 218.61 branch misses 145.86k cycles 519.58k instructions 11.91k c-refs 161.49 c-misses summary object-equals 1.17x faster than are-deeply-equal 1.19x faster than node.isDeepStrictEqual 1.21x faster than fast-equals 1.37x faster than lodash.isEqual 1.98x faster than dequal • Object with mixed primitive values [size=4096] ------------------------------------------- ------------------------------- object-equals 694.95 µs/iter 697.87 µs █ (668.01 µs … 965.24 µs) 875.89 µs █ (128.17 kb … 472.88 kb) 146.34 kb ██▅▄▃▄▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁ 1.53 ipc ( 93.01% cache) 53.78k branch misses 2.78M cycles 4.26M instructions 238.90k c-refs 16.70k c-misses are-deeply-equal 780.04 µs/iter 771.63 µs █ (744.29 µs … 1.09 ms) 984.91 µs █ (192.45 kb … 225.16 kb) 219.22 kb ▅██▃▁▂▃▂▁▁▁▁▁▁▁▁▁▂▁▁▁ 1.51 ipc ( 93.07% cache) 59.82k branch misses 3.12M cycles 4.69M instructions 270.51k c-refs 18.75k c-misses fast-equals 792.80 µs/iter 786.30 µs █ (765.39 µs … 1.06 ms) 966.10 µs █▅ (128.17 kb … 161.13 kb) 146.09 kb ▃██▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 1.65 ipc ( 93.61% cache) 54.22k branch misses 3.02M cycles 4.98M instructions 228.87k c-refs 14.62k c-misses dequal 946.56 µs/iter 966.24 µs ▄█▄ (893.81 µs … 1.09 ms) 1.01 ms ▄▆ ▂▅███ (128.14 kb … 161.02 kb) 146.09 kb ▃████▅▆▅▅██████▂▂▂▂▂▂ 1.71 ipc ( 93.57% cache) 56.42k branch misses 3.72M cycles 6.36M instructions 253.60k c-refs 16.31k c-misses lodash.isEqual 842.46 µs/iter 849.78 µs ▃ █ (792.04 µs … 1.47 ms) 1.08 ms █ █ (122.71 kb … 877.27 kb) 221.88 kb ▇████▃▂▂▁▁▂▂▁▁▁▁▂▁▁▁▁ 1.60 ipc ( 93.82% cache) 61.95k branch misses 3.29M cycles 5.26M instructions 283.99k c-refs 17.55k c-misses node.isDeepStrictEqual 747.63 µs/iter 747.81 µs █▃ (730.85 µs … 954.62 µs) 834.74 µs ▆██ ( 31.64 kb … 419.14 kb) 219.24 kb ▄████▃▂▂▂▂▁▁▁▁▁▂▁▁▁▁▁ 1.56 ipc ( 93.31% cache) 58.20k branch misses 3.04M cycles 4.75M instructions 259.66k c-refs 17.36k c-misses summary object-equals 1.08x faster than node.isDeepStrictEqual 1.12x faster than are-deeply-equal 1.14x faster than fast-equals 1.21x faster than lodash.isEqual 1.36x faster than dequal • Object with mixed primitive values [size=16386] ------------------------------------------- ------------------------------- object-equals 3.91 ms/iter 3.92 ms █ (3.76 ms … 4.64 ms) 4.60 ms ▄█ (512.23 kb … 513.94 kb) 512.24 kb ███▅▅▃▂▂▃▁▂▂▁▃▁▂▁▁▁▂▁ 1.35 ipc ( 77.60% cache) 259.96k branch misses 13.65M cycles 18.49M instructions 1.30M c-refs 290.68k c-misses are-deeply-equal 4.39 ms/iter 4.40 ms █ (4.26 ms … 5.19 ms) 4.97 ms ▅█▇ (768.54 kb … 769.88 kb) 768.55 kb ▂████▇▂▂▁▃▂▁▂▂▁▁▁▁▁▁▁ 1.36 ipc ( 77.82% cache) 290.04k branch misses 15.28M cycles 20.78M instructions 1.49M c-refs 331.41k c-misses fast-equals 4.12 ms/iter 4.11 ms █ (3.99 ms … 5.11 ms) 5.00 ms █▂ (512.23 kb … 513.62 kb) 512.24 kb ▅██▄▄▂▁▂▁▁▁▁▂▁▁▂▁▁▁▁▁ 1.51 ipc ( 77.98% cache) 254.54k branch misses 14.62M cycles 22.15M instructions 1.32M c-refs 289.71k c-misses dequal 4.77 ms/iter 4.82 ms █▆▅ (4.45 ms … 5.60 ms) 5.35 ms ███▂ (466.64 kb … 560.23 kb) 512.23 kb ▄▂▄▂▃▇████▃▄▁▃▁▁▁▁▁▁▂ 1.58 ipc ( 77.95% cache) 266.50k branch misses 17.32M cycles 27.39M instructions 1.36M c-refs 300.32k c-misses lodash.isEqual 4.48 ms/iter 4.58 ms █ (4.20 ms … 5.44 ms) 5.30 ms ██ ▇▂ (634.64 kb … 1.94 mb) 779.98 kb ██▆▆▄██▆▄▂▃▃▄▄▂▂▂▂▃▁▂ 1.41 ipc ( 77.74% cache) 292.93k branch misses 15.96M cycles 22.47M instructions 1.55M c-refs 345.63k c-misses node.isDeepStrictEqual 4.32 ms/iter 4.33 ms █▂ (4.26 ms … 4.97 ms) 4.70 ms ██▃ (768.36 kb … 771.55 kb) 768.38 kb ▇███▅▃▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 1.34 ipc ( 76.76% cache) 289.44k branch misses 15.16M cycles 20.24M instructions 1.42M c-refs 329.65k c-misses summary object-equals 1.06x faster than fast-equals 1.11x faster than node.isDeepStrictEqual 1.12x faster than are-deeply-equal 1.15x faster than lodash.isEqual 1.22x faster than dequal ``` </details> ### Nested Object with mixed primitive values | Library | 16 | 512 | 4096 | 16386 | Speed Range | | :--- | :--- | :--- | :--- | :--- | :--- | | object-equals | 3.99 µs | 180.93 µs | 8.53 ms | 36.73 ms | 1.00x (baseline) | | fast-equals | 18.66 µs | 659.85 µs | 11.73 ms | 51.14 ms | 4.68x-1.39x slower | | dequal | 19.09 µs | 1.01 ms | 13.57 ms | 61.98 ms | 4.79x-1.69x slower | | node.isDeepStrictEqual | 19.45 µs | 608.04 µs | 11.21 ms | 51.27 ms | 4.88x-1.40x slower | | are-deeply-equal | 20.47 µs | 677.69 µs | 13.38 ms | 61.65 ms | 5.13x-1.68x slower | | lodash.isEqual | 29.15 µs | 1.04 ms | 16.18 ms | 71.95 ms | 7.31x-1.96x slower | <details> <summary>Full benchmark results with hardware counters</summary> ```console clk: ~3.82 GHz cpu: AMD Ryzen 5 3600 6-Core Processor runtime: node 24.1.0 (x64-linux) benchmark avg (min … max) p75 / p99 (min … top 1%) ------------------------------------------- ------------------------------- • Nested Object with mixed primitive values [size=16] ------------------------------------------- ------------------------------- object-equals 3.99 µs/iter 4.03 µs ▄ █ (3.91 µs … 4.12 µs) 4.10 µs █ ▅█▅ ▅▅ ▅ ( 7.22 kb … 7.23 kb) 7.22 kb ██▅███▅▅▅██▁▅▅▁▅█▁▅█▅ 3.24 ipc ( 97.94% cache) 26.27 branch misses 16.30k cycles 52.82k instructions 982.95 c-refs 20.25 c-misses are-deeply-equal 20.47 µs/iter 20.37 µs █ (20.02 µs … 21.59 µs) 21.45 µs ███ ( 10.36 kb … 10.37 kb) 10.37 kb ████▁█▁▁▁▁▁▁▁▁▁▁▁▁▁██ 2.79 ipc ( 98.30% cache) 66.78 branch misses 77.81k cycles 216.94k instructions 1.95k c-refs 33.17 c-misses fast-equals 18.66 µs/iter 19.00 µs ▇ █ (17.12 µs … 200.50 µs) 23.56 µs ▇█▅ █▇▂ ( 4.59 kb … 252.41 kb) 7.74 kb ▁███████▅▂▁▁▁▁▁▁▁▁▁▁▁ 2.73 ipc ( 98.48% cache) 56.79 branch misses 75.22k cycles 205.56k instructions 1.97k c-refs 29.99 c-misses dequal 19.09 µs/iter 19.11 µs █ █ (18.69 µs … 19.89 µs) 19.54 µs ▅▅ ▅▅ █ ▅█ ▅ ▅ ( 3.61 kb … 3.62 kb) 3.61 kb ██▁▁██▁█▁██▁█▁▁▁▁▁▁▁█ 2.68 ipc ( 99.00% cache) 26.64 branch misses 78.03k cycles 208.85k instructions 1.49k c-refs 14.96 c-misses lodash.isEqual 29.15 µs/iter 28.89 µs █ (27.93 µs … 252.78 µs) 35.56 µs ▇█ ( 2.03 kb … 612.27 kb) 14.95 kb ▁██▇▂▁▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁ 2.66 ipc ( 97.83% cache) 63.46 branch misses 121.31k cycles 322.50k instructions 5.77k c-refs 125.45 c-misses node.isDeepStrictEqual 19.45 µs/iter 19.27 µs █ (17.27 µs … 237.33 µs) 26.13 µs █ (912.00 b … 273.44 kb) 9.12 kb ▁▁▁██▇▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.72 ipc ( 98.67% cache) 56.87 branch misses 76.01k cycles 206.97k instructions 2.51k c-refs 33.23 c-misses summary object-equals 4.68x faster than fast-equals 4.79x faster than dequal 4.88x faster than node.isDeepStrictEqual 5.13x faster than are-deeply-equal 7.31x faster than lodash.isEqual • Nested Object with mixed primitive values [size=512] ------------------------------------------- ------------------------------- object-equals 180.93 µs/iter 180.51 µs █ (174.24 µs … 434.02 µs) 213.86 µs ▄█ (232.00 b … 643.56 kb) 237.28 kb ▁██▇▆▅▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.96 ipc ( 80.12% cache) 911.68 branch misses 699.13k cycles 2.07M instructions 68.75k c-refs 13.67k c-misses are-deeply-equal 677.69 µs/iter 688.34 µs ██ (636.52 µs … 991.67 µs) 819.38 µs ▅▅ ██ (338.62 kb … 384.68 kb) 341.70 kb ▃██▇▆██▃▂▁▁▁▁▁▁▁▁▁▁▁▁ 2.69 ipc ( 79.63% cache) 2.30k branch misses 2.67M cycles 7.16M instructions 152.67k c-refs 31.11k c-misses fast-equals 659.85 µs/iter 649.81 µs █ (609.59 µs … 1.07 ms) 847.68 µs █ (236.17 kb … 256.20 kb) 236.40 kb ▁▅██▃▁▁▁▁▂▁▂▂▄▃▁▁▁▁▁▁ 2.76 ipc ( 79.59% cache) 1.27k branch misses 2.46M cycles 6.78M instructions 109.44k c-refs 22.33k c-misses dequal 1.01 ms/iter 1.01 ms █ (973.07 µs … 1.25 ms) 1.13 ms ▄█▅ (126.14 kb … 324.13 kb) 128.48 kb ▃█▇███▅▂▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.49 ipc ( 75.68% cache) 2.88k branch misses 3.86M cycles 9.61M instructions 114.36k c-refs 27.81k c-misses lodash.isEqual 1.04 ms/iter 1.04 ms █▂ (987.58 µs … 1.32 ms) 1.19 ms ██ (232.80 kb … 1.11 mb) 443.21 kb ▂▂▄▄██▆▃▂▁▂▂▁▁▁▁▁▁▁▁▁ 2.59 ipc ( 87.38% cache) 6.13k branch misses 4.03M cycles 10.44M instructions 257.68k c-refs 32.53k c-misses node.isDeepStrictEqual 608.04 µs/iter 610.65 µs █ (585.32 µs … 873.17 µs) 718.15 µs ▄██▇ (237.37 kb … 333.46 kb) 284.31 kb ▃████▇▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 2.73 ipc ( 76.99% cache) 1.21k branch misses 2.49M cycles 6.77M instructions 112.22k c-refs 25.82k c-misses summary object-equals 3.36x faster than node.isDeepStrictEqual 3.65x faster than fast-equals 3.75x faster than are-deeply-equal 5.56x faster than dequal 5.74x faster than lodash.isEqual • Nested Object with mixed primitive values [size=4096] ------------------------------------------- ------------------------------- object-equals 8.53 ms/iter 8.55 ms █▃ (8.06 ms … 9.91 ms) 9.84 ms ███ ( 2.13 mb … 2.16 mb) 2.14 mb ███▃▇▄▁▁▂▁▁▂▄▁▁▃▁▂▇▄▄ 1.50 ipc ( 80.90% cache) 71.66k branch misses 32.60M cycles 48.79M instructions 1.92M c-refs 366.23k c-misses are-deeply-equal 13.38 ms/iter 13.32 ms ▆█ (12.94 ms … 15.53 ms) 15.48 ms ▅██ ( 2.27 mb … 3.17 mb) 3.14 mb ████▄▄▃▁▄▁▁▁▁▁▁▁▁▁▁▁▆ 1.75 ipc ( 86.71% cache) 101.11k branch misses 51.17M cycles 89.53M instructions 3.17M c-refs 421.32k c-misses fast-equals 11.73 ms/iter 11.80 ms ▄█ ▄ █ (11.60 ms … 12.06 ms) 11.96 ms █████ ▅▅ ██ █ ( 2.13 mb … 2.16 mb) 2.14 mb ██████████▅██▁█▁█▁▅▁█ 1.64 ipc ( 76.24% cache) 72.18k branch misses 45.14M cycles 74.07M instructions 1.66M c-refs 394.89k c-misses dequal 13.57 ms/iter 13.79 ms █ (13.17 ms … 13.89 ms) 13.89 ms ▆▆▃ ▆ ▃ █▃▃▆▆▃ ( 1.28 mb … 1.29 mb) 1.29 mb ▄███▄█▁▄█▄▁▄▁▄▁██████ 1.80 ipc ( 82.98% cache) 84.35k branch misses 53.82M cycles 96.98M instructions 2.06M c-refs 350.62k c-misses lodash.isEqual 16.18 ms/iter 16.47 ms █ (15.81 ms … 16.82 ms) 16.80 ms █▃ ( 4.01 mb … 4.46 mb) 4.02 mb ▃▇██▅▁▅▁▁▃▅▃▃▃▅▁█▁▃▃▃ 1.81 ipc ( 93.16% cache) 112.62k branch misses 65.35M cycles 118.22M instructions 6.91M c-refs 472.58k c-misses node.isDeepStrictEqual 11.21 ms/iter 11.25 ms ▂█▂ █ (11.06 ms … 11.57 ms) 11.46 ms ▅███▇▂█▇▂ ( 2.51 mb … 2.54 mb) 2.54 mb ▄▄█████████▄▁▄▄▄▇▄▁▁▄ 1.63 ipc ( 86.14% cache) 78.78k branch misses 45.80M cycles 74.53M instructions 2.79M c-refs 386.88k c-misses summary object-equals 1.31x faster than node.isDeepStrictEqual 1.38x faster than fast-equals 1.57x faster than are-deeply-equal 1.59x faster than dequal 1.9x faster than lodash.isEqual • Nested Object with mixed primitive values [size=16386] ------------------------------------------- ------------------------------- object-equals 36.73 ms/iter 36.77 ms █ (36.36 ms … 37.72 ms) 37.60 ms ▂ █ ▇ ▂ ( 8.60 mb … 8.60 mb) 8.60 mb █▁█▆█▁▁█▁▁▁▁▁▁▁▆▁▁▁▁▆ 1.32 ipc ( 74.96% cache) 327.27k branch misses 148.62M cycles 195.86M instructions 7.08M c-refs 1.77M c-misses are-deeply-equal 61.65 ms/iter 61.46 ms █ (60.66 ms … 65.22 ms) 63.17 ms ██ █ ( 12.50 mb … 12.56 mb) 12.53 mb ███▁▁██▁█▁▁▁▁▁▁▁▁▁▁▁█ 1.46 ipc ( 81.40% cache) 443.13k branch misses 246.26M cycles 358.88M instructions 12.60M c-refs 2.34M c-misses fast-equals 51.14 ms/iter 51.15 ms ██ (50.93 ms … 51.50 ms) 51.47 ms ▅██▅ ▅ ▅▅ ( 8.58 mb … 8.58 mb) 8.58 mb ████▁▁▁▁█▁▁▁▁▁▁▁▁▁▁██ 1.45 ipc ( 74.16% cache) 324.73k branch misses 208.75M cycles 303.38M instructions 7.99M c-refs 2.07M c-misses dequal 61.98 ms/iter 62.01 ms ██ █ █ (61.29 ms … 64.30 ms) 62.51 ms ▅ ▅██ █ █ ▅ ( 5.17 mb … 5.19 mb) 5.19 mb █▁▁▁███▁█▁▁▁█▁▁▁▁▁▁▁█ 1.57 ipc ( 79.06% cache) 389.79k branch misses 252.13M cycles 396.10M instructions 9.83M c-refs 2.06M c-misses lodash.isEqual 71.95 ms/iter 72.71 ms █ (69.40 ms … 79.58 ms) 74.03 ms █ █ ( 16.13 mb … 16.21 mb) 16.14 mb ██▁█▁▁▁▁▁██▁▁▁█▁█▁▁▁█ 1.70 ipc ( 91.63% cache) 493.84k branch misses 283.53M cycles 482.36M instructions 29.31M c-refs 2.45M c-misses node.isDeepStrictEqual 51.27 ms/iter 51.36 ms █ █ ██ ██ █ █ █ (51.03 ms … 51.56 ms) 51.48 ms █ █ ██ ██ █ █ █ ( 10.10 mb … 10.13 mb) 10.13 mb █▁█▁▁▁██▁██▁▁▁▁█▁█▁▁█ 1.47 ipc ( 83.72% cache) 354.52k branch misses 208.80M cycles 306.59M instructions 12.95M c-refs 2.11M c-misses summary object-equals 1.39x faster than fast-equals 1.4x faster than node.isDeepStrictEqual 1.68x faster than are-deeply-equal 1.69x faster than dequal 1.96x faster than lodash.isEqual ``` </details> ### Array with mixed primitive values | Library | 16 | 512 | 4096 | 16386 | Speed Range | | :--- | :--- | :--- | :--- | :--- | :--- | | object-equals | 82.33 ns | 2.39 µs | 17.81 µs | 72.42 µs | 1.00x (baseline) | | dequal | 148.52 ns | 4.06 µs | 32.60 µs | 134.75 µs | 1.80x-1.86x slower | | fast-equals | 161.44 ns | 4.32 µs | 33.20 µs | 137.47 µs | 1.96x-1.90x slower | | are-deeply-equal | 203.61 ns | 4.05 µs | 32.62 µs | 136.20 µs | 2.47x-1.88x slower | | lodash.isEqual | 230.45 ns | 3.75 µs | 27.93 µs | 109.87 µs | 2.80x-1.52x slower | | node.isDeepStrictEqual | 462.38 ns | 4.31 µs | 30.62 µs | 121.78 µs | 5.62x-1.68x slower | <details> <summary>Full benchmark results with hardware counters</summary> ```console clk: ~3.70 GHz cpu: AMD Ryzen 5 3600 6-Core Processor runtime: node 24.1.0 (x64-linux) benchmark avg (min … max) p75 / p99 (min … top 1%) ------------------------------------------- ------------------------------- • Array with mixed primitive values [size=16] ------------------------------------------- ------------------------------- object-equals 82.33 ns/iter 82.15 ns █▅ (78.53 ns … 173.76 ns) 113.85 ns ██ ( 0.10 b … 104.21 b) 0.41 b ▆██▆▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁ 4.03 ipc ( 86.99% cache) 0.01 branch misses 334.20 cycles 1.35k instructions 0.09 c-refs 0.01 c-misses are-deeply-equal 203.61 ns/iter 206.48 ns █ (191.05 ns … 272.43 ns) 250.34 ns █▆ █ ( 23.86 b … 328.23 b) 184.24 b ▃██▆▅█▇▃▂▁▁▁▂▁▁▂▂▂▂▁▁ 3.14 ipc ( 95.95% cache) 1.02 branch misses 808.21 cycles 2.54k instructions 6.29 c-refs 0.25 c-misses fast-equals 161.44 ns/iter 163.63 ns █ (156.54 ns … 238.54 ns) 176.34 ns ████ █ ( 0.09 b … 144.15 b) 0.68 b ▅█████▄██▇▃▂▂▁▁▁▁▁▁▁▁ 3.71 ipc ( 99.96% cache) 1.01 branch misses 622.41 cycles 2.31k instructions 28.00 c-refs 0.01 c-misses dequal 148.52 ns/iter 151.87 ns █▅ (137.42 ns … 198.44 ns) 166.51 ns ▂▂▇██ ▇▄ ( 0.09 b … 130.16 b) 0.54 b ▂▇█▇██████▃▃██▄▂▁▁▁▁▁ 3.70 ipc ( 90.00% cache) 1.01 branch misses 581.78 cycles 2.15k instructions 0.09 c-refs 0.01 c-misses lodash.isEqual 230.45 ns/iter 230.05 ns █ (221.05 ns … 347.38 ns) 279.52 ns ▂█▇ (220.38 b … 762.50 b) 528.25 b ▃███▆▃▂▁▁▁▁▁▁▁▁▁▁▁▂▂▁ 3.37 ipc ( 95.93% cache) 1.03 branch misses 946.63 cycles 3.19k instructions 18.02 c-refs 0.73 c-misses node.isDeepStrictEqual 462.38 ns/iter 460.00 ns █ (420.00 ns … 44.22 µs) 660.00 ns ▃█ (440.00 b … 465.69 kb) 453.76 b ▁▂██▂▂▃▃▁▁▁▁▁▁▁▁▁▁▁▁▁ 1.61 ipc ( 99.76% cache) 31.05 branch misses 3.26k cycles 5.27k instructions 379.29 c-refs 0.91 c-misses summary object-equals 1.8x faster than dequal 1.96x faster than fast-equals 2.47x faster than are-deeply-equal 2.8x faster than lodash.isEqual 5.62x faster than node.isDeepStrictEqual • Array with mixed primitive values [size=512] ------------------------------------------- ------------------------------- object-equals 2.39 µs/iter 2.43 µs ▂ ▂ █▂▅ (2.18 µs … 2.76 µs) 2.68 µs ▅▂▅█▂█▅███ ▂ ▂ ▂ ( 0.10 b … 0.53 b) 0.11 b ▄██████████▇▁█▁█▄█▄▇▄ 3.73 ipc ( 99.96% cache) 1.04 branch misses 9.77k cycles 36.41k instructions 1.02k c-refs 0.43 c-misses are-deeply-equal 4.05 µs/iter 4.13 µs █ (3.84 µs … 4.57 µs) 4.27 µs ▃▃█ ██▃▃▃ ( 48.96 b … 184.50 b) 180.71 b ███▄▄▁█▁▁▄▁▁█████▁▁▁▄ 3.84 ipc ( 99.73% cache) 1.10 branch misses 16.24k cycles 62.38k instructions 499.13 c-refs 1.35 c-misses fast-equals 4.32 µs/iter 4.35 µs █ (4.19 µs … 4.89 µs) 4.81 µs █ ▃▃ ( 0.09 b … 0.45 b) 0.10 b █▇██▅▅▃▃▁▁▅▁▁▃▁▁▁▃▁▁▃ 4.00 ipc ( 99.86% cache) 2.10 branch misses 16.48k cycles 65.94k instructions 415.35 c-refs 0.57 c-misses dequal 4.06 µs/iter 4.09 µs █▃ (3.98 µs … 4.28 µs) 4.25 µs ██▃ ( 0.09 b … 0.41 b) 0.10 b ▆████▄▁▆█▄▁▁▁▁▁▆▁▄▄▁▆ 3.97 ipc ( 99.89% cache) 1.06 branch misses 15.71k cycles 62.33k instructions 270.23 c-refs 0.31 c-misses lodash.isEqual 3.75 µs/iter 3.75 µs ▃█ (3.66 µs … 4.66 µs) 4.06 µs ██ █▇ (519.58 b … 551.58 b) 528.92 b ██▆██▆▁▃▆▃▁▁▃▁▁▁▁▁▁▁▃ 4.15 ipc ( 99.27% cache) 1.18 branch misses 14.62k cycles 60.69k instructions 487.42 c-refs 3.54 c-misses node.isDeepStrictEqual 4.31 µs/iter 4.34 µs ▃ █ ▃█