@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
Markdown
[](https://www.npmjs.com/package/@observ33r/object-equals)
[](https://bundlephobia.com/package/@observ33r/object-equals)
[](https://github.com/observ33r/object-equals/blob/main/LICENSE)
[](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 ▃ █ ▃█