Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

assert,util: improve deep object comparison performance #57648

Merged

Conversation

BridgeAR
Copy link
Member

@BridgeAR BridgeAR commented Mar 27, 2025

This improves the performance for almost all objects when comparing
them deeply significantly.

assert/deepequal-buffer.js method='deepEqual' arrayBuffer=0 strict=0 len=100 n=20000                                        -0.64 %       ±0.69%  ±0.92%  ±1.20%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=0 strict=0 len=1000 n=20000                               ***     -1.27 %       ±0.60%  ±0.80%  ±1.04%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=0 strict=1 len=100 n=20000                                ***      3.67 %       ±0.56%  ±0.74%  ±0.97%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=0 strict=1 len=1000 n=20000                               ***      3.46 %       ±0.82%  ±1.09%  ±1.42%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=1 strict=0 len=100 n=20000                                        -0.54 %       ±0.93%  ±1.24%  ±1.62%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=1 strict=0 len=1000 n=20000                                       -0.61 %       ±0.92%  ±1.23%  ±1.61%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=1 strict=1 len=100 n=20000                                ***      5.76 %       ±1.12%  ±1.49%  ±1.94%
assert/deepequal-buffer.js method='deepEqual' arrayBuffer=1 strict=1 len=1000 n=20000                               ***      5.59 %       ±0.70%  ±0.93%  ±1.21%
assert/deepequal-buffer.js method='notDeepEqual' arrayBuffer=0 strict=1 len=100 n=20000                             ***      4.45 %       ±1.03%  ±1.38%  ±1.79%
assert/deepequal-buffer.js method='notDeepEqual' arrayBuffer=0 strict=1 len=1000 n=20000                            ***      5.28 %       ±1.12%  ±1.50%  ±1.97%
assert/deepequal-buffer.js method='notDeepEqual' arrayBuffer=1 strict=1 len=100 n=20000                             ***      6.42 %       ±1.30%  ±1.74%  ±2.26%
assert/deepequal-buffer.js method='notDeepEqual' arrayBuffer=1 strict=1 len=1000 n=20000                            ***      5.74 %       ±0.78%  ±1.04%  ±1.35%
assert/deepequal-buffer.js method='partial' arrayBuffer=0 strict=1 len=100 n=20000                                   **      1.13 %       ±0.67%  ±0.89%  ±1.15%
assert/deepequal-buffer.js method='partial' arrayBuffer=0 strict=1 len=1000 n=20000                                         -0.53 %       ±0.60%  ±0.80%  ±1.04%
assert/deepequal-buffer.js method='partial' arrayBuffer=1 strict=1 len=100 n=20000                                  ***     -2.42 %       ±0.76%  ±1.01%  ±1.31%
assert/deepequal-buffer.js method='partial' arrayBuffer=1 strict=1 len=1000 n=20000                                  **     -0.83 %       ±0.52%  ±0.70%  ±0.91%
assert/deepequal-buffer.js method='unequal_length' arrayBuffer=0 strict=1 len=100 n=20000                           ***      3.22 %       ±1.49%  ±1.98%  ±2.59%
assert/deepequal-buffer.js method='unequal_length' arrayBuffer=0 strict=1 len=1000 n=20000                          ***      2.15 %       ±0.93%  ±1.24%  ±1.61%
assert/deepequal-buffer.js method='unequal_length' arrayBuffer=1 strict=1 len=100 n=20000                           ***      2.98 %       ±0.97%  ±1.29%  ±1.68%
assert/deepequal-buffer.js method='unequal_length' arrayBuffer=1 strict=1 len=1000 n=20000                          ***      5.88 %       ±0.80%  ±1.06%  ±1.38%
assert/deepequal-map.js method='deepEqual_mixed' strict=0 len=500 n=2000                                            ***     43.30 %       ±1.28%  ±1.72%  ±2.27%
assert/deepequal-map.js method='deepEqual_mixed' strict=1 len=500 n=2000                                            ***     73.10 %       ±0.87%  ±1.16%  ±1.53%
assert/deepequal-map.js method='deepEqual_objectOnly' strict=0 len=500 n=2000                                       ***     77.15 %       ±0.63%  ±0.85%  ±1.11%
assert/deepequal-map.js method='deepEqual_objectOnly' strict=1 len=500 n=2000                                       ***    101.62 %       ±1.21%  ±1.63%  ±2.16%
assert/deepequal-map.js method='deepEqual_primitiveOnly' strict=0 len=500 n=2000                                    ***     15.62 %       ±1.29%  ±1.72%  ±2.24%
assert/deepequal-map.js method='deepEqual_primitiveOnly' strict=1 len=500 n=2000                                    ***     14.63 %       ±1.83%  ±2.44%  ±3.20%
assert/deepequal-map.js method='notDeepEqual_mixed' strict=0 len=500 n=2000                                         ***      4.34 %       ±2.33%  ±3.10%  ±4.05%
assert/deepequal-map.js method='notDeepEqual_mixed' strict=1 len=500 n=2000                                                  1.24 %       ±2.89%  ±3.86%  ±5.04%
assert/deepequal-map.js method='notDeepEqual_objectOnly' strict=0 len=500 n=2000                                    ***     43.55 %       ±0.47%  ±0.63%  ±0.82%
assert/deepequal-map.js method='notDeepEqual_objectOnly' strict=1 len=500 n=2000                                    ***     68.34 %       ±0.46%  ±0.61%  ±0.80%
assert/deepequal-map.js method='notDeepEqual_primitiveOnly' strict=0 len=500 n=2000                                 ***     13.75 %       ±2.22%  ±2.96%  ±3.85%
assert/deepequal-map.js method='notDeepEqual_primitiveOnly' strict=1 len=500 n=2000                                 ***     13.56 %       ±2.29%  ±3.06%  ±3.99%
assert/deepequal-object.js method='deepEqual' size=10000 n=50                                                       ***     77.16 %       ±0.94%  ±1.26%  ±1.66%
assert/deepequal-object.js method='deepStrictEqual' size=10000 n=50                                                 ***     59.75 %       ±0.85%  ±1.14%  ±1.49%
assert/deepequal-object.js method='notDeepEqual' size=10000 n=50                                                    ***     13.82 %       ±5.52%  ±7.43%  ±9.84%
assert/deepequal-object.js method='notDeepStrictEqual' size=10000 n=50                                              ***     15.59 %       ±2.85%  ±3.80%  ±4.94%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='array'                  ***      9.19 %       ±0.52%  ±0.69%  ±0.90%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='boolean'                ***      6.78 %       ±1.63%  ±2.16%  ±2.82%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='circular'               ***     30.83 %       ±1.73%  ±2.31%  ±3.02%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='date'                           -0.24 %       ±1.22%  ±1.63%  ±2.12%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='empty_object'           ***     -7.41 %       ±2.73%  ±3.64%  ±4.75%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='number'                  **      3.24 %       ±2.15%  ±2.86%  ±3.74%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='object'                 ***     43.14 %       ±1.32%  ±1.77%  ±2.33%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='regexp'                   *     -1.69 %       ±1.34%  ±1.79%  ±2.33%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='set_object'               *     -0.75 %       ±0.66%  ±0.87%  ±1.14%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='set_simple'                     -0.28 %       ±1.08%  ±1.45%  ±1.90%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=0 n=100000 primitive='string'                 ***      3.41 %       ±1.93%  ±2.57%  ±3.34%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='array'                  ***     27.25 %       ±0.94%  ±1.25%  ±1.63%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='boolean'                ***      7.07 %       ±2.00%  ±2.67%  ±3.48%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='circular'               ***     31.68 %       ±0.65%  ±0.87%  ±1.13%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='date'                   ***     13.20 %       ±0.72%  ±0.96%  ±1.25%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='empty_object'           ***     15.22 %       ±1.11%  ±1.48%  ±1.94%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='number'                   *      2.07 %       ±1.72%  ±2.28%  ±2.97%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='object'                 ***     39.89 %       ±1.32%  ±1.75%  ±2.28%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='regexp'                 ***     15.33 %       ±1.00%  ±1.34%  ±1.75%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='set_object'             ***     13.76 %       ±1.03%  ±1.38%  ±1.81%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='set_simple'             ***     11.82 %       ±0.97%  ±1.30%  ±1.71%
assert/deepequal-prims-and-objs-big-loop.js method='deepEqual' strict=1 n=100000 primitive='string'                 ***      4.80 %       ±1.61%  ±2.15%  ±2.79%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='array'               ***     24.14 %       ±0.59%  ±0.79%  ±1.03%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='boolean'             ***      3.88 %       ±1.45%  ±1.92%  ±2.51%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='circular'            ***     45.59 %       ±0.96%  ±1.28%  ±1.68%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='date'                ***     20.66 %       ±1.95%  ±2.60%  ±3.41%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='empty_object'        ***     36.60 %       ±1.89%  ±2.51%  ±3.27%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='number'                *     -2.15 %       ±1.65%  ±2.19%  ±2.85%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='object'              ***    -33.17 %       ±1.00%  ±1.33%  ±1.74%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='regexp'              ***     17.37 %       ±1.66%  ±2.22%  ±2.90%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='set_object'          ***     15.22 %       ±0.80%  ±1.07%  ±1.39%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='set_simple'          ***     12.18 %       ±0.89%  ±1.19%  ±1.56%
assert/deepequal-prims-and-objs-big-loop.js method='notDeepEqual' strict=1 n=100000 primitive='string'                       0.60 %       ±1.48%  ±1.97%  ±2.57%
assert/deepequal-set.js method='deepEqual_mixed' order='insert' strict=0 len=120 n=1000                             ***     28.43 %       ±0.71%  ±0.95%  ±1.23%
assert/deepequal-set.js method='deepEqual_mixed' order='insert' strict=0 len=2 n=1000                               ***     35.04 %       ±2.00%  ±2.66%  ±3.47%
assert/deepequal-set.js method='deepEqual_mixed' order='insert' strict=1 len=120 n=1000                             ***     45.14 %       ±1.41%  ±1.88%  ±2.46%
assert/deepequal-set.js method='deepEqual_mixed' order='insert' strict=1 len=2 n=1000                               ***     35.68 %       ±1.72%  ±2.29%  ±2.98%
assert/deepequal-set.js method='deepEqual_mixed' order='reversed' strict=0 len=120 n=1000                           ***   1507.82 %       ±6.76%  ±9.11% ±12.10%
assert/deepequal-set.js method='deepEqual_mixed' order='reversed' strict=0 len=2 n=1000                             ***     39.52 %       ±2.26%  ±3.01%  ±3.91%
assert/deepequal-set.js method='deepEqual_mixed' order='reversed' strict=1 len=120 n=1000                           ***   1904.21 %       ±6.66%  ±8.97% ±11.91%
assert/deepequal-set.js method='deepEqual_mixed' order='reversed' strict=1 len=2 n=1000                             ***     35.28 %       ±2.32%  ±3.09%  ±4.04%
assert/deepequal-set.js method='deepEqual_objectOnly' order='insert' strict=0 len=120 n=1000                        ***     44.43 %       ±1.60%  ±2.15%  ±2.84%
assert/deepequal-set.js method='deepEqual_objectOnly' order='insert' strict=0 len=2 n=1000                          ***     36.89 %       ±1.54%  ±2.05%  ±2.67%
assert/deepequal-set.js method='deepEqual_objectOnly' order='insert' strict=1 len=120 n=1000                        ***     70.90 %       ±0.76%  ±1.02%  ±1.33%
assert/deepequal-set.js method='deepEqual_objectOnly' order='insert' strict=1 len=2 n=1000                          ***     34.78 %       ±1.79%  ±2.38%  ±3.11%
assert/deepequal-set.js method='deepEqual_objectOnly' order='random' strict=1 len=120 n=1000                        ***     37.27 %       ±3.09%  ±4.11%  ±5.37%
assert/deepequal-set.js method='deepEqual_objectOnly' order='random' strict=1 len=2 n=1000                          ***     35.59 %       ±3.02%  ±4.03%  ±5.25%
assert/deepequal-set.js method='deepEqual_objectOnly' order='reversed' strict=0 len=120 n=1000                      ***   3983.35 %      ±13.63% ±18.37% ±24.38%
assert/deepequal-set.js method='deepEqual_objectOnly' order='reversed' strict=0 len=2 n=1000                        ***     30.14 %       ±1.19%  ±1.58%  ±2.06%
assert/deepequal-set.js method='deepEqual_objectOnly' order='reversed' strict=1 len=120 n=1000                      ***   5327.60 %      ±24.09% ±32.47% ±43.11%
assert/deepequal-set.js method='deepEqual_objectOnly' order='reversed' strict=1 len=2 n=1000                        ***     30.62 %       ±1.56%  ±2.08%  ±2.71%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='insert' strict=0 len=120 n=1000                       *     -1.47 %       ±1.10%  ±1.47%  ±1.93%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='insert' strict=0 len=2 n=1000                       ***      5.18 %       ±1.93%  ±2.57%  ±3.35%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='insert' strict=1 len=120 n=1000                             -0.39 %       ±1.43%  ±1.91%  ±2.49%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='insert' strict=1 len=2 n=1000                       ***      5.66 %       ±2.05%  ±2.75%  ±3.61%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='random' strict=1 len=120 n=1000                       *     -1.68 %       ±1.29%  ±1.72%  ±2.25%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='random' strict=1 len=2 n=1000                       ***      5.46 %       ±1.79%  ±2.39%  ±3.12%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='reversed' strict=0 len=120 n=1000                           -1.42 %       ±1.73%  ±2.31%  ±3.04%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='reversed' strict=0 len=2 n=1000                      **      3.26 %       ±2.04%  ±2.72%  ±3.55%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='reversed' strict=1 len=120 n=1000                            0.13 %       ±1.32%  ±1.76%  ±2.30%
assert/deepequal-set.js method='deepEqual_primitiveOnly' order='reversed' strict=1 len=2 n=1000                     ***      6.23 %       ±2.12%  ±2.83%  ±3.70%
assert/deepequal-set.js method='notDeepEqual_mixed' order='insert' strict=0 len=120 n=1000                          ***      5.15 %       ±1.54%  ±2.05%  ±2.66%
assert/deepequal-set.js method='notDeepEqual_mixed' order='insert' strict=0 len=2 n=1000                            ***      3.65 %       ±2.09%  ±2.78%  ±3.62%
assert/deepequal-set.js method='notDeepEqual_mixed' order='insert' strict=1 len=120 n=1000                           **      3.92 %       ±2.59%  ±3.46%  ±4.53%
assert/deepequal-set.js method='notDeepEqual_mixed' order='insert' strict=1 len=2 n=1000                            ***      6.55 %       ±1.58%  ±2.11%  ±2.74%
assert/deepequal-set.js method='notDeepEqual_mixed' order='random' strict=1 len=120 n=1000                                  17.74 %      ±18.15% ±24.16% ±31.45%
assert/deepequal-set.js method='notDeepEqual_mixed' order='random' strict=1 len=2 n=1000                                    -2.43 %       ±5.54%  ±7.44%  ±9.81%
assert/deepequal-set.js method='notDeepEqual_mixed' order='reversed' strict=0 len=120 n=1000                        ***      6.41 %       ±1.92%  ±2.56%  ±3.34%
assert/deepequal-set.js method='notDeepEqual_mixed' order='reversed' strict=0 len=2 n=1000                          ***    -11.30 %       ±1.24%  ±1.65%  ±2.15%
assert/deepequal-set.js method='notDeepEqual_mixed' order='reversed' strict=1 len=120 n=1000                        ***      4.16 %       ±2.15%  ±2.86%  ±3.73%
assert/deepequal-set.js method='notDeepEqual_mixed' order='reversed' strict=1 len=2 n=1000                          ***    -14.19 %       ±1.58%  ±2.11%  ±2.76%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='insert' strict=0 len=120 n=1000                     ***     26.18 %       ±0.91%  ±1.21%  ±1.58%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='insert' strict=0 len=2 n=1000                       ***     33.08 %       ±1.51%  ±2.00%  ±2.61%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='insert' strict=1 len=120 n=1000                     ***     48.18 %       ±0.80%  ±1.08%  ±1.42%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='insert' strict=1 len=2 n=1000                       ***     32.15 %       ±1.65%  ±2.20%  ±2.87%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='reversed' strict=0 len=120 n=1000                   ***   3157.41 %      ±22.60% ±30.46% ±40.44%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='reversed' strict=0 len=2 n=1000                     ***     62.08 %       ±1.99%  ±2.65%  ±3.46%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='reversed' strict=1 len=120 n=1000                   ***   4008.03 %      ±10.50% ±14.15% ±18.79%
assert/deepequal-set.js method='notDeepEqual_objectOnly' order='reversed' strict=1 len=2 n=1000                     ***     57.50 %       ±2.20%  ±2.95%  ±3.86%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='insert' strict=0 len=120 n=1000                           0.54 %       ±1.11%  ±1.48%  ±1.93%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='insert' strict=0 len=2 n=1000                     **      2.55 %       ±1.84%  ±2.45%  ±3.20%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='insert' strict=1 len=120 n=1000                    *     -2.46 %       ±2.00%  ±2.67%  ±3.49%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='insert' strict=1 len=2 n=1000                    ***      3.48 %       ±1.75%  ±2.33%  ±3.04%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='random' strict=1 len=120 n=1000                           6.57 %      ±18.39% ±24.47% ±31.85%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='random' strict=1 len=2 n=1000                    ***      6.19 %       ±1.98%  ±2.63%  ±3.43%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='reversed' strict=0 len=120 n=1000                ***     -9.69 %       ±1.66%  ±2.21%  ±2.88%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='reversed' strict=0 len=2 n=1000                  ***      4.27 %       ±1.58%  ±2.10%  ±2.73%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='reversed' strict=1 len=120 n=1000                ***     -7.19 %       ±2.05%  ±2.74%  ±3.58%
assert/deepequal-set.js method='notDeepEqual_primitiveOnly' order='reversed' strict=1 len=2 n=1000                  ***      7.20 %       ±2.10%  ±2.80%  ±3.65%
assert/deepequal-simple-array-and-set.js method='deepEqual_Array' strict=1 len=10000 n=1000                         ***     68.73 %       ±3.54%  ±4.77%  ±6.33%
assert/deepequal-simple-array-and-set.js method='deepEqual_Set' strict=1 len=10000 n=1000                                   -5.87 %       ±7.67% ±10.22% ±13.36%
assert/deepequal-simple-array-and-set.js method='deepEqual_sparseArray' strict=1 len=10000 n=1000                   ***     14.35 %       ±0.43%  ±0.58%  ±0.76%
assert/deepequal-simple-array-and-set.js method='notDeepEqual_Array' strict=1 len=10000 n=1000                      ***     69.65 %       ±3.73%  ±5.02%  ±6.66%
assert/deepequal-simple-array-and-set.js method='notDeepEqual_Set' strict=1 len=10000 n=1000                                 0.46 %       ±1.21%  ±1.60%  ±2.09%
assert/deepequal-simple-array-and-set.js method='notDeepEqual_sparseArray' strict=1 len=10000 n=1000                ***     13.56 %       ±0.62%  ±0.84%  ±1.10%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=0 n=25000 type='Float32Array'                     ***     -6.23 %       ±1.50%  ±1.99%  ±2.59%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=0 n=25000 type='Int8Array'                                -0.42 %       ±0.59%  ±0.78%  ±1.02%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=0 n=25000 type='Uint32Array'                              -0.50 %       ±1.00%  ±1.33%  ±1.73%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=0 n=25000 type='Uint8Array'                               -0.63 %       ±0.98%  ±1.31%  ±1.70%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=1 n=25000 type='Float32Array'                     ***      4.13 %       ±0.79%  ±1.05%  ±1.38%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=1 n=25000 type='Int8Array'                        ***      4.36 %       ±0.91%  ±1.22%  ±1.58%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=1 n=25000 type='Uint32Array'                      ***      3.55 %       ±1.08%  ±1.44%  ±1.87%
assert/deepequal-typedarrays.js len=100 method='deepEqual' strict=1 n=25000 type='Uint8Array'                       ***      3.45 %       ±0.93%  ±1.24%  ±1.61%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=0 n=25000 type='Float32Array'                  ***     -2.72 %       ±1.28%  ±1.70%  ±2.21%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=0 n=25000 type='Int8Array'                       *     -1.20 %       ±1.14%  ±1.52%  ±1.98%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=0 n=25000 type='Uint32Array'                    **     -2.16 %       ±1.36%  ±1.81%  ±2.36%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=0 n=25000 type='Uint8Array'                     **     -1.73 %       ±1.27%  ±1.70%  ±2.22%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=1 n=25000 type='Float32Array'                  ***      3.22 %       ±0.98%  ±1.31%  ±1.71%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=1 n=25000 type='Int8Array'                     ***      3.30 %       ±1.27%  ±1.70%  ±2.21%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=1 n=25000 type='Uint32Array'                   ***      2.66 %       ±1.09%  ±1.45%  ±1.89%
assert/deepequal-typedarrays.js len=100 method='notDeepEqual' strict=1 n=25000 type='Uint8Array'                    ***      4.22 %       ±1.17%  ±1.56%  ±2.03%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=0 n=25000 type='Int8Array'                        **     -0.93 %       ±0.57%  ±0.76%  ±0.99%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=0 n=25000 type='Uint32Array'                       *     -0.91 %       ±0.82%  ±1.10%  ±1.43%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=0 n=25000 type='Uint8Array'                      ***     -1.30 %       ±0.72%  ±0.96%  ±1.24%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=1 n=25000 type='Float32Array'                    ***      2.03 %       ±0.66%  ±0.89%  ±1.17%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=1 n=25000 type='Int8Array'                       ***      3.20 %       ±0.90%  ±1.20%  ±1.57%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=1 n=25000 type='Uint32Array'                     ***      2.66 %       ±0.42%  ±0.56%  ±0.73%
assert/deepequal-typedarrays.js len=5000 method='deepEqual' strict=1 n=25000 type='Uint8Array'                      ***      4.24 %       ±1.25%  ±1.68%  ±2.22%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=0 n=25000 type='Int8Array'                    ***     -2.16 %       ±0.93%  ±1.24%  ±1.62%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=0 n=25000 type='Uint32Array'                  ***     -2.39 %       ±0.60%  ±0.80%  ±1.04%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=0 n=25000 type='Uint8Array'                   ***     -1.42 %       ±0.79%  ±1.06%  ±1.38%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=1 n=25000 type='Float32Array'                 ***      1.62 %       ±0.74%  ±0.99%  ±1.29%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=1 n=25000 type='Int8Array'                    ***      2.96 %       ±1.14%  ±1.52%  ±1.99%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=1 n=25000 type='Uint32Array'                    *      1.15 %       ±0.91%  ±1.22%  ±1.60%
assert/deepequal-typedarrays.js len=5000 method='notDeepEqual' strict=1 n=25000 type='Uint8Array'                   ***      3.06 %       ±1.05%  ±1.39%  ±1.81%
assert/partial-deep-equal.js datasetName='array' extraProps=0 size=500 n=125                                        ***     29.54 %       ±3.92%  ±5.21%  ±6.78%
assert/partial-deep-equal.js datasetName='array' extraProps=1 size=500 n=125                                        ***     31.72 %       ±5.40%  ±7.24%  ±9.54%
assert/partial-deep-equal.js datasetName='arrayBuffers' extraProps=0 size=500 n=125                                         -0.65 %       ±0.69%  ±0.92%  ±1.20%
assert/partial-deep-equal.js datasetName='arrayBuffers' extraProps=1 size=500 n=125                                         -0.27 %       ±0.72%  ±0.96%  ±1.26%
assert/partial-deep-equal.js datasetName='circularRefs' extraProps=0 size=500 n=125                                 ***     11.14 %       ±0.43%  ±0.57%  ±0.74%
assert/partial-deep-equal.js datasetName='circularRefs' extraProps=1 size=500 n=125                                 ***     11.71 %       ±0.97%  ±1.30%  ±1.71%
assert/partial-deep-equal.js datasetName='dataViewArrayBuffers' extraProps=0 size=500 n=125                                 -0.39 %       ±0.93%  ±1.24%  ±1.61%
assert/partial-deep-equal.js datasetName='dataViewArrayBuffers' extraProps=1 size=500 n=125                                  0.54 %       ±0.96%  ±1.29%  ±1.69%
assert/partial-deep-equal.js datasetName='maps' extraProps=0 size=500 n=125                                         ***     64.71 %       ±2.00%  ±2.69%  ±3.56%
assert/partial-deep-equal.js datasetName='maps' extraProps=1 size=500 n=125                                         ***     68.27 %       ±1.01%  ±1.35%  ±1.75%
assert/partial-deep-equal.js datasetName='objects' extraProps=0 size=500 n=125                                      ***     63.01 %       ±0.78%  ±1.05%  ±1.37%
assert/partial-deep-equal.js datasetName='objects' extraProps=1 size=500 n=125                                      ***     64.22 %       ±0.89%  ±1.19%  ±1.55%
assert/partial-deep-equal.js datasetName='sets' extraProps=0 size=500 n=125                                         ***     62.31 %       ±0.74%  ±0.98%  ±1.28%
assert/partial-deep-equal.js datasetName='sets' extraProps=1 size=500 n=125                                         ***     70.55 %       ±0.88%  ±1.17%  ±1.52%
assert/partial-deep-equal.js datasetName='setsWithObjects' extraProps=0 size=500 n=125                              ***     57.70 %       ±0.96%  ±1.28%  ±1.68%
assert/partial-deep-equal.js datasetName='setsWithObjects' extraProps=1 size=500 n=125                              ***     52.33 %       ±1.02%  ±1.37%  ±1.79%
assert/partial-deep-equal.js datasetName='typedArrays' extraProps=0 size=500 n=125                                  ***      3.51 %       ±1.26%  ±1.69%  ±2.22%
assert/partial-deep-equal.js datasetName='typedArrays' extraProps=1 size=500 n=125                                  ***      2.92 %       ±0.82%  ±1.10%  ±1.43%

@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/performance

Sorry, something went wrong.

@nodejs-github-bot nodejs-github-bot added assert Issues and PRs related to the assert subsystem. needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels Mar 27, 2025
Copy link
Member

@ljharb ljharb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good, just some thoughts

@BridgeAR BridgeAR force-pushed the assert-object-performance-improvement branch from 717c5ac to c9b2d34 Compare April 2, 2025 23:59
@BridgeAR BridgeAR marked this pull request as ready for review April 2, 2025 23:59
Copy link

codecov bot commented Apr 3, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.27%. Comparing base (9aa57bf) to head (75d8fbb).
Report is 4 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #57648      +/-   ##
==========================================
+ Coverage   90.24%   90.27%   +0.02%     
==========================================
  Files         630      630              
  Lines      184990   185129     +139     
  Branches    36216    36259      +43     
==========================================
+ Hits       166948   167116     +168     
+ Misses      11003    10984      -19     
+ Partials     7039     7029      -10     
Files with missing lines Coverage Δ
lib/internal/util/comparisons.js 100.00% <100.00%> (+0.36%) ⬆️

... and 22 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@BridgeAR BridgeAR requested review from ljharb, targos and aduh95 April 3, 2025 12:41
@BridgeAR
Copy link
Member Author

BridgeAR commented Apr 3, 2025

@BridgeAR BridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 4, 2025
@github-actions github-actions bot added request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. and removed request-ci Add this label to start a Jenkins CI on a PR. labels Apr 4, 2025
Copy link
Contributor

github-actions bot commented Apr 4, 2025

Failed to start CI
   ⚠  Commits were pushed since the last approving review:
   ⚠  - assert,util: improve deep object comparison performance
   ⚠  - assert,util: improve deep equal comparison performance
   ⚠  - assert,util: improve (partial) deep equal comparison performance
   ⚠  - test: add assert.deepStrictEqual test cases to cover more cases
   ✘  Refusing to run CI on potentially unsafe PR
https://github.com/nodejs/node/actions/runs/14264748421

Copy link
Member

@bengl bengl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broadly speaking, a lot of these optimizations are very non-obvious, and could use some commentary. That said, the reasons why become clearer on multiple reads, so I'm not going to block on that.

The one about getting the descriptor instead of using ObjectPropertyIsEnumerable still stands though.

BridgeAR added 4 commits April 4, 2025 19:48

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
This improves the performance for almost all objects when comparing
them deeply.
This allows the compiler to inline parts of the code in a way that
especially primitives in arrays can be compared faster.
The circular check is now done lazily. That way only users that
actually make use of such structures have to do the calculation
overhead. It is an initial overhead the very first time it's run
to detect the circular structure, while every following call uses
the check for circular structures by default. This improves the
performance for object comparison significantly.

On top of that, this includes an optimised algorithm for sets and
maps that contain objects as keys. The tracking is now done in an
array and the array size is not changed when elements at the start
or at the end of the array is detected. The order of the elements
matter, so a reversed key order is now a magnitude faster. Insert
sort comparison is also signficantly faster, random order is a tad
faster.
@BridgeAR BridgeAR force-pushed the assert-object-performance-improvement branch from ccea4ca to 75d8fbb Compare April 4, 2025 18:08
@BridgeAR BridgeAR added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. and removed request-ci-failed An error occurred while starting CI via request-ci label, and manual interventon is needed. labels Apr 4, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 4, 2025
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@BridgeAR BridgeAR added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Apr 5, 2025
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 5, 2025
@nodejs-github-bot nodejs-github-bot merged commit e739559 into nodejs:main Apr 5, 2025
67 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in e739559

JonasBa pushed a commit to JonasBa/node that referenced this pull request Apr 11, 2025
This improves the performance for almost all objects when comparing
them deeply.

PR-URL: nodejs#57648
Reviewed-By: Jordan Harband <[email protected]>
Reviewed-By: Bryan English <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assert Issues and PRs related to the assert subsystem. author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants