mirror: A fast canonicalisation utility for stable object equality
0

Configure Feed

Select the types of activity you want to include in your feed.

docs: 1.67x is much easier than 67%

Marais Rossouw (Jun 25, 2026, 10:59 AM +1000) 3a3d5a6e 709e2975

+68 -70
+67 -67
readme.md
··· 62 62 <!-- BEGIN BENCHMARK --> 63 63 64 64 ``` 65 - ✔ simple ~ 1.1µs @ 945,104 ops/sec ± 0.16% 66 - ✔ deep ~ 8.2µs @ 121,541 ops/sec ± 1.34% 67 - ✔ deep circular ~ 5.3µs @ 187,820 ops/sec ± 0.18% 68 - ✔ big ~ 80.2µs @ 12,476 ops/sec ± 0.12% 69 - ✔ leafy ~ 23.0µs @ 43,393 ops/sec ± 0.74% 65 + ✔ simple ~ 1.1µs @ 921,139 ops/sec ± 1.00% 66 + ✔ deep ~ 8.0µs @ 125,088 ops/sec ± 0.38% 67 + ✔ deep circular ~ 5.5µs @ 182,804 ops/sec ± 3.19% 68 + ✔ big ~ 85.1µs @ 11,753 ops/sec ± 1.08% 69 + ✔ leafy ~ 24.2µs @ 41,307 ops/sec ± 0.17% 70 70 ``` 71 71 72 72 <details><summary>All candidates</summary> 73 73 74 74 ``` 75 75 simple 76 - ✔ object-identity ~ 1.1µs @ 945,104 ops/sec ± 0.16% 77 - ✔ safe-stable-stringify ~ 1.7µs @ 597,318 ops/sec ± 0.12% 78 - ✔ ohash ~ 3.5µs @ 285,053 ops/sec ± 0.16% 79 - ✔ object-hash ~ 9.7µs @ 102,648 ops/sec ± 1.63% 80 - ✔ hash-it † ~ 2.7µs @ 364,144 ops/sec ± 2.48% 81 - ✔ json-stable-stringify ~ 3.0µs @ 329,228 ops/sec ± 0.03% 82 - ✔ fast-json-stable-stringify ~ 2.0µs @ 491,338 ops/sec ± 0.16% 83 - ✔ tiny-stable-stringify ~ 2.3µs @ 432,540 ops/sec ± 0.07% 84 - ✔ json-stringify-deterministic ~ 3.5µs @ 285,498 ops/sec ± 1.10% 85 - ✔ json-stable-stringify-without-jsonify ~ 3.1µs @ 321,857 ops/sec ± 2.79% 86 - ✔ json-sorted-stringify ~ 2.3µs @ 428,881 ops/sec ± 1.60% 87 - ✔ canonicalize ~ 3.4µs @ 298,473 ops/sec ± 0.44% 76 + ✔ object-identity ~ 1.1µs @ 921,139 ops/sec ± 1.00% 77 + ✔ safe-stable-stringify ~ 1.8µs @ 560,158 ops/sec ± 0.91% 78 + ✔ ohash ~ 3.6µs @ 280,116 ops/sec ± 3.31% 79 + ✔ object-hash ~ 10.0µs @ 99,840 ops/sec ± 0.57% 80 + ✔ hash-it † ~ 2.9µs @ 342,544 ops/sec ± 2.11% 81 + ✔ json-stable-stringify ~ 3.1µs @ 326,547 ops/sec ± 0.03% 82 + ✔ fast-json-stable-stringify ~ 2.0µs @ 488,763 ops/sec ± 0.31% 83 + ✔ tiny-stable-stringify ~ 2.4µs @ 413,527 ops/sec ± 2.38% 84 + ✔ json-stringify-deterministic ~ 3.4µs @ 291,605 ops/sec ± 2.59% 85 + ✔ json-stable-stringify-without-jsonify ~ 3.1µs @ 325,385 ops/sec ± 3.23% 86 + ✔ json-sorted-stringify ~ 2.4µs @ 412,511 ops/sec ± 1.40% 87 + ✔ canonicalize ~ 3.4µs @ 296,935 ops/sec ± 0.24% 88 88 ✘ @tufjs/canonical-json 89 - ───────────────────────────────────────────────────────────────────────── 90 - ⭐︎ object-identity (58.2% faster than safe-stable-stringify) 89 + ────────────────────────────────────────────────────────────────────────── 90 + ⭐︎ object-identity (1.64x faster than safe-stable-stringify) 91 91 92 92 deep 93 - ✔ object-identity ~ 8.2µs @ 121,541 ops/sec ± 1.34% 94 - ✔ safe-stable-stringify ~ 13.4µs @ 74,884 ops/sec ± 2.03% 95 - ✔ ohash ~ 26.1µs @ 38,307 ops/sec ± 0.25% 96 - ✔ object-hash ~ 55.8µs @ 17,923 ops/sec ± 0.23% 97 - ✔ hash-it † ~ 21.3µs @ 47,041 ops/sec ± 1.80% 98 - ✔ json-stable-stringify ~ 23.1µs @ 43,253 ops/sec ± 1.96% 99 - ✔ fast-json-stable-stringify ~ 13.7µs @ 72,892 ops/sec ± 1.60% 100 - ✔ tiny-stable-stringify ~ 16.0µs @ 62,547 ops/sec ± 2.16% 101 - ✔ json-stringify-deterministic ~ 24.5µs @ 40,785 ops/sec ± 0.76% 102 - ✔ json-stable-stringify-without-jsonify ~ 23.0µs @ 43,476 ops/sec ± 1.99% 103 - ✔ json-sorted-stringify ~ 15.3µs @ 65,257 ops/sec ± 0.48% 104 - ✔ canonicalize ~ 27.0µs @ 36,974 ops/sec ± 0.78% 105 - ✔ @tufjs/canonical-json ~ 35.5µs @ 28,130 ops/sec ± 0.96% 93 + ✔ object-identity ~ 8.0µs @ 125,088 ops/sec ± 0.38% 94 + ✔ safe-stable-stringify ~ 12.9µs @ 77,399 ops/sec ± 1.32% 95 + ✔ ohash ~ 24.7µs @ 40,429 ops/sec ± 0.95% 96 + ✔ object-hash ~ 53.3µs @ 18,759 ops/sec ± 1.67% 97 + ✔ hash-it † ~ 21.1µs @ 47,501 ops/sec ± 1.24% 98 + ✔ json-stable-stringify ~ 22.8µs @ 43,850 ops/sec ± 1.34% 99 + ✔ fast-json-stable-stringify ~ 13.6µs @ 73,448 ops/sec ± 0.84% 100 + ✔ tiny-stable-stringify ~ 16.5µs @ 60,768 ops/sec ± 4.79% 101 + ✔ json-stringify-deterministic ~ 23.3µs @ 42,915 ops/sec ± 1.65% 102 + ✔ json-stable-stringify-without-jsonify ~ 22.4µs @ 44,583 ops/sec ± 1.17% 103 + ✔ json-sorted-stringify ~ 15.4µs @ 64,737 ops/sec ± 0.73% 104 + ✔ canonicalize ~ 25.4µs @ 39,367 ops/sec ± 1.58% 105 + ✔ @tufjs/canonical-json ~ 33.7µs @ 29,649 ops/sec ± 1.79% 106 106 ────────────────────────────────────────────────────────────────────────── 107 - ⭐︎ object-identity (62.3% faster than safe-stable-stringify) 107 + ⭐︎ object-identity (1.62x faster than safe-stable-stringify) 108 108 109 109 deep circular 110 - ✔ object-identity ~ 5.3µs @ 187,820 ops/sec ± 0.18% 111 - ✔ safe-stable-stringify ~ 7.2µs @ 138,610 ops/sec ± 0.34% 112 - ✔ ohash ~ 16.4µs @ 61,113 ops/sec ± 0.58% 113 - ✔ object-hash ~ 44.5µs @ 22,492 ops/sec ± 0.37% 114 - ✔ hash-it † ~ 15.2µs @ 65,867 ops/sec ± 0.10% 110 + ✔ object-identity ~ 5.5µs @ 182,804 ops/sec ± 3.19% 111 + ✔ safe-stable-stringify ~ 7.3µs @ 136,207 ops/sec ± 2.78% 112 + ✔ ohash ~ 16.3µs @ 61,293 ops/sec ± 0.40% 113 + ✔ object-hash ~ 44.6µs @ 22,433 ops/sec ± 1.20% 114 + ✔ hash-it † ~ 15.3µs @ 65,287 ops/sec ± 0.38% 115 115 ✘ json-stable-stringify 116 116 ✘ fast-json-stable-stringify 117 117 ✘ tiny-stable-stringify ··· 121 121 ✘ canonicalize 122 122 ✘ @tufjs/canonical-json 123 123 ────────────────────────────────────────────────────────────────────────── 124 - ⭐︎ object-identity (35.5% faster than safe-stable-stringify) 124 + ⭐︎ object-identity (1.34x faster than safe-stable-stringify) 125 125 126 126 big 127 - ✔ object-identity ~ 80.2µs @ 12,476 ops/sec ± 0.12% 128 - ✔ safe-stable-stringify ~ 134.8µs @ 7,418 ops/sec ± 0.70% 129 - ✔ ohash ~ 288.8µs @ 3,463 ops/sec ± 0.30% 130 - ✔ object-hash ~ 488.0µs @ 2,049 ops/sec ± 1.21% 131 - ✔ hash-it † ~ 258.4µs @ 3,870 ops/sec ± 0.01% 132 - ✔ json-stable-stringify ~ 212.1µs @ 4,715 ops/sec ± 0.26% 133 - ✔ fast-json-stable-stringify ~ 155.9µs @ 6,416 ops/sec ± 0.44% 134 - ✔ tiny-stable-stringify ~ 165.5µs @ 6,043 ops/sec ± 0.27% 135 - ✔ json-stringify-deterministic ~ 261.1µs @ 3,830 ops/sec ± 0.14% 136 - ✔ json-stable-stringify-without-jsonify ~ 213.3µs @ 4,688 ops/sec ± 0.04% 137 - ✔ json-sorted-stringify ~ 169.8µs @ 5,888 ops/sec ± 1.58% 138 - ✔ canonicalize ~ 256.6µs @ 3,897 ops/sec ± 0.13% 139 - ✔ @tufjs/canonical-json ~ 371.5µs @ 2,692 ops/sec ± 0.09% 127 + ✔ object-identity ~ 85.1µs @ 11,753 ops/sec ± 1.08% 128 + ✔ safe-stable-stringify ~ 140.5µs @ 7,119 ops/sec ± 0.17% 129 + ✔ ohash ~ 294.4µs @ 3,397 ops/sec ± 0.81% 130 + ✔ object-hash ~ 499.8µs @ 2,001 ops/sec ± 1.02% 131 + ✔ hash-it † ~ 272.9µs @ 3,665 ops/sec ± 0.90% 132 + ✔ json-stable-stringify ~ 220.2µs @ 4,541 ops/sec ± 1.63% 133 + ✔ fast-json-stable-stringify ~ 155.9µs @ 6,415 ops/sec ± 0.69% 134 + ✔ tiny-stable-stringify ~ 165.3µs @ 6,050 ops/sec ± 0.02% 135 + ✔ json-stringify-deterministic ~ 262.1µs @ 3,815 ops/sec ± 0.12% 136 + ✔ json-stable-stringify-without-jsonify ~ 221.9µs @ 4,506 ops/sec ± 0.79% 137 + ✔ json-sorted-stringify ~ 173.8µs @ 5,754 ops/sec ± 0.04% 138 + ✔ canonicalize ~ 248.1µs @ 4,030 ops/sec ± 0.24% 139 + ✔ @tufjs/canonical-json ~ 369.1µs @ 2,709 ops/sec ± 0.02% 140 140 ────────────────────────────────────────────────────────────────────────── 141 - ⭐︎ object-identity (68.2% faster than safe-stable-stringify) 141 + ⭐︎ object-identity (1.65x faster than safe-stable-stringify) 142 142 143 143 leafy 144 - ✔ object-identity ~ 23.0µs @ 43,393 ops/sec ± 0.74% 145 - ✔ safe-stable-stringify ~ 49.0µs @ 20,402 ops/sec ± 0.54% 146 - ✔ ohash ~ 30.7µs @ 32,569 ops/sec ± 2.43% 147 - ✔ object-hash ~ 83.9µs @ 11,922 ops/sec ± 2.53% 148 - ✔ hash-it † ~ 81.8µs @ 12,230 ops/sec ± 1.05% 149 - ✔ json-stable-stringify ~ 112.2µs @ 8,912 ops/sec ± 1.22% 150 - ✔ fast-json-stable-stringify ~ 56.2µs @ 17,781 ops/sec ± 1.54% 151 - ✔ tiny-stable-stringify ~ 106.3µs @ 9,410 ops/sec ± 1.94% 152 - ✔ json-stringify-deterministic ~ 125.3µs @ 7,982 ops/sec ± 0.41% 153 - ✔ json-stable-stringify-without-jsonify ~ 112.4µs @ 8,895 ops/sec ± 2.44% 154 - ✔ json-sorted-stringify ~ 102.7µs @ 9,740 ops/sec ± 0.12% 155 - ✔ canonicalize ~ 89.0µs @ 11,239 ops/sec ± 0.67% 156 - ✔ @tufjs/canonical-json ~ 208.9µs @ 4,786 ops/sec ± 0.50% 144 + ✔ object-identity ~ 24.2µs @ 41,307 ops/sec ± 0.17% 145 + ✔ safe-stable-stringify ~ 50.7µs @ 19,733 ops/sec ± 0.26% 146 + ✔ ohash ~ 30.4µs @ 32,871 ops/sec ± 1.66% 147 + ✔ object-hash ~ 82.7µs @ 12,096 ops/sec ± 0.04% 148 + ✔ hash-it † ~ 80.2µs @ 12,467 ops/sec ± 0.62% 149 + ✔ json-stable-stringify ~ 108.4µs @ 9,227 ops/sec ± 0.08% 150 + ✔ fast-json-stable-stringify ~ 56.5µs @ 17,685 ops/sec ± 1.11% 151 + ✔ tiny-stable-stringify ~ 103.3µs @ 9,678 ops/sec ± 0.41% 152 + ✔ json-stringify-deterministic ~ 121.2µs @ 8,248 ops/sec ± 0.13% 153 + ✔ json-stable-stringify-without-jsonify ~ 111.9µs @ 8,936 ops/sec ± 0.12% 154 + ✔ json-sorted-stringify ~ 103.9µs @ 9,626 ops/sec ± 0.35% 155 + ✔ canonicalize ~ 90.2µs @ 11,085 ops/sec ± 0.15% 156 + ✔ @tufjs/canonical-json ~ 209.4µs @ 4,776 ops/sec ± 0.34% 157 157 ────────────────────────────────────────────────────────────────────────── 158 - ⭐︎ object-identity (33.2% faster than ohash) 158 + ⭐︎ object-identity (1.26x faster than ohash) 159 159 ``` 160 160 161 161 </details>
+1 -3
scripts/bench.ts
··· 76 76 const ranked = rows[g].filter((r) => r.ops != null).sort((a, b) => b.ops! - a.ops!); 77 77 const [win, alt] = ranked; 78 78 if (win) { 79 - const ahead = alt 80 - ? ` (${((win.ops! / alt.ops! - 1) * 100).toFixed(1)}% faster than ${alt.name})` 81 - : ''; 79 + const ahead = alt ? ` (${(win.ops! / alt.ops!).toFixed(2)}x faster than ${alt.name})` : ''; 82 80 lines.push('─'.repeat(Math.max(...lines.map((l) => l.length))), `⭐︎ ${win.name}${ahead}`); 83 81 } 84 82