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: improve performance #13973

Closed
wants to merge 3 commits into from

Conversation

BridgeAR
Copy link
Member

While refactoring the assert in #13862 I stumbled open a couple of improvements. This change is only about performance changes and not about style.

I added a few more benchmarks and fixed the description of the old ones.

Benchmarks
                                                                                                                     improvement confidence      p.value
 assert/deepequal-buffer.js method="deepEqual" len=100 n=500000                                                           2.33 %            7.316323e-01
 assert/deepequal-buffer.js method="deepStrictEqual" len=100 n=500000                                                     0.04 %            9.930054e-01
 assert/deepequal-buffer.js method="notDeepEqual" len=100 n=500000                                                       -5.85 %            2.784226e-01
 assert/deepequal-buffer.js method="notDeepStrictEqual" len=100 n=500000                                                 -5.59 %            3.001234e-01
 assert/deepequal-object.js method="deepEqual" size=100 n=10000                                                          50.46 %        *** 2.288171e-18
 assert/deepequal-object.js method="deepEqual" size=1000 n=1000                                                          67.95 %        *** 3.059217e-30
 assert/deepequal-object.js method="deepEqual" size=10000 n=100                                                          79.66 %        *** 9.207480e-33
 assert/deepequal-object.js method="deepStrictEqual" size=100 n=10000                                                    65.35 %        *** 3.240965e-23
 assert/deepequal-object.js method="deepStrictEqual" size=1000 n=1000                                                    81.71 %        *** 1.205872e-28
 assert/deepequal-object.js method="deepStrictEqual" size=10000 n=100                                                    94.75 %        *** 5.241022e-29
 assert/deepequal-object.js method="notDeepEqual" size=100 n=10000                                                      229.85 %        *** 1.889593e-23
 assert/deepequal-object.js method="notDeepEqual" size=1000 n=1000                                                      608.17 %        *** 4.146461e-26
 assert/deepequal-object.js method="notDeepEqual" size=10000 n=100                                                     1062.95 %        *** 2.408876e-33
 assert/deepequal-object.js method="notDeepStrictEqual" size=100 n=10000                                                242.26 %        *** 1.586300e-22
 assert/deepequal-object.js method="notDeepStrictEqual" size=1000 n=1000                                                622.27 %        *** 2.609994e-26
 assert/deepequal-object.js method="notDeepStrictEqual" size=10000 n=100                                               1064.28 %        *** 5.299886e-27
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="array"                 510.02 %        *** 2.595144e-27
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="boolean"               515.89 %        *** 3.743109e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="new-array"             513.81 %        *** 3.622029e-33
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="null"                  519.45 %        *** 5.168069e-32
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="number"                506.67 %        *** 1.843979e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="object"                516.84 %        *** 1.017218e-31
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="string"                511.24 %        *** 2.280310e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Array" len=100000 n=25 prim="undefined"             515.58 %        *** 4.776631e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="array"                    31.11 %        *** 9.964406e-23
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="boolean"                  31.64 %        *** 1.781798e-19
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="new-array"                30.52 %        *** 4.417665e-20
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="null"                     26.33 %        *** 2.951717e-06
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="number"                   19.30 %        *** 3.005158e-07
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="object"                   29.05 %        *** 1.158809e-17
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="string"                   31.94 %        *** 2.672107e-16
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="undefined"                25.14 %        *** 1.475360e-04
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="array"           512.38 %        *** 9.062277e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="boolean"         520.17 %        *** 1.775437e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="new-array"       510.74 %        *** 1.518219e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="null"            519.06 %        *** 2.101566e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="number"          504.35 %        *** 1.429286e-25
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="object"          512.10 %        *** 1.181912e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="string"          515.83 %        *** 4.265263e-32
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Array" len=100000 n=25 prim="undefined"       514.06 %        *** 2.112530e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="array"              29.32 %        *** 3.259328e-19
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="boolean"            24.08 %        *** 3.541972e-05
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="new-array"          31.80 %        *** 7.752780e-26
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="null"               31.01 %        *** 2.799161e-26
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="number"             28.69 %        *** 9.321106e-15
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="object"             29.79 %        *** 3.149769e-22
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="string"             30.36 %        *** 5.547048e-24
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="undefined"          33.25 %        *** 9.415303e-15
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="array"              498.52 %        *** 4.150282e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="boolean"            503.56 %        *** 4.086493e-27
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="new-array"          499.51 %        *** 8.200783e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="null"               502.45 %        *** 7.676734e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="number"             497.00 %        *** 5.051971e-29
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="object"             504.16 %        *** 9.443596e-27
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="string"             500.16 %        *** 6.245976e-29
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Array" len=100000 n=25 prim="undefined"          506.09 %        *** 5.548733e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="array"                 38.99 %        *** 2.117152e-21
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="boolean"               41.34 %        *** 8.039099e-13
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="new-array"             34.59 %        *** 4.047460e-08
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="null"                  40.82 %        *** 1.008765e-11
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="number"                41.32 %        *** 3.700953e-18
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="object"                43.00 %        *** 3.259377e-15
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="string"                41.71 %        *** 2.297337e-16
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="undefined"             42.77 %        *** 1.315782e-25
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="array"        500.61 %        *** 2.938624e-25
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="boolean"      509.20 %        *** 3.660616e-29
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="new-array"    502.57 %        *** 2.517452e-29
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="null"         507.65 %        *** 1.022300e-31
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="number"       495.83 %        *** 2.382429e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="object"       506.00 %        *** 1.020662e-29
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="string"       504.18 %        *** 8.501536e-32
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Array" len=100000 n=25 prim="undefined"    508.25 %        *** 8.319102e-37
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="array"           39.18 %        *** 1.174312e-23
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="boolean"         41.92 %        *** 6.687850e-17
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="new-array"       38.17 %        *** 7.104991e-24
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="null"            38.26 %        *** 1.134893e-17
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="number"          39.22 %        *** 9.407632e-21
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="object"          40.20 %        *** 5.403801e-14
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="string"          39.22 %        *** 6.780387e-24
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="undefined"       36.45 %        *** 2.965572e-10
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="array"                                   -3.34 %        *** 9.582538e-09
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="boolean"                                 -3.16 %        *** 1.354914e-05
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="new-array"                               -5.34 %        *** 2.144227e-04
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="null"                                    -3.63 %        *** 6.492770e-07
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="number"                                  -3.15 %         ** 6.193770e-03
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="object"                                  -2.63 %         ** 1.635324e-03
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="string"                                  -3.61 %        *** 5.859919e-07
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="undefined"                               -3.80 %        *** 8.281596e-05
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="array"                              6.93 %        *** 3.282310e-10
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="boolean"                            6.47 %        *** 2.540042e-11
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="new-array"                          5.41 %        *** 1.114413e-08
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="null"                               7.37 %        *** 8.377163e-11
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="number"                             5.75 %        *** 2.572949e-11
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="object"                             6.25 %        *** 2.319331e-07
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="string"                             5.74 %        *** 8.195711e-14
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="undefined"                          4.92 %        *** 2.495528e-04
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="array"                                27.98 %        *** 3.872747e-20
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="boolean"                              -2.18 %         ** 3.618656e-03
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="new-array"                            28.03 %        *** 3.314333e-28
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="null"                                 -1.86 %          * 2.765366e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="number"                               -2.71 %         ** 3.011431e-03
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="object"                               25.20 %        *** 4.464850e-16
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="string"                               -2.22 %          * 1.423177e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="undefined"                            -1.91 %          * 2.223972e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="array"                          20.30 %        *** 6.285555e-22
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="boolean"                         7.98 %        *** 2.964258e-14
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="new-array"                      20.61 %        *** 1.250668e-21
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="null"                            7.87 %        *** 1.945697e-09
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="number"                          7.78 %        *** 3.784016e-13
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="object"                         18.37 %        *** 2.987944e-18
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="string"                          8.33 %        *** 7.416061e-16
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="undefined"                       7.66 %        *** 5.268512e-14
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Float32Array"                                 825.51 %        *** 1.769654e-26
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Float64Array"                                 830.17 %        *** 7.208875e-30
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Int16Array"                                     0.74 %            3.572383e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Int32Array"                                     0.33 %            8.281712e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Int8Array"                                      2.12 %            1.004341e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Uint16Array"                                    0.97 %            3.406747e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Uint32Array"                                   -0.53 %            7.429723e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Uint8Array"                                     1.22 %            2.354753e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepEqual" n=1 type="Uint8ClampedArray"                              1.94 %            1.373714e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Float32Array"                           828.24 %        *** 1.710967e-27
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Float64Array"                           829.86 %        *** 6.907388e-29
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Int16Array"                               0.47 %            4.531061e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Int32Array"                               1.08 %            1.685682e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Int8Array"                                0.48 %            4.986249e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Uint16Array"                              0.26 %            7.337130e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Uint32Array"                             -0.07 %            8.645550e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Uint8Array"                              -0.35 %            5.936551e-01
 assert/deepequal-typedarrays.js len=1000000 method="deepStrictEqual" n=1 type="Uint8ClampedArray"                       -0.05 %            8.619136e-01
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Float32Array"                              986.37 %        *** 5.592733e-27
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Float64Array"                              987.71 %        *** 2.506846e-26
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Int16Array"                                993.93 %        *** 2.601085e-38
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Int32Array"                                984.40 %        *** 3.427367e-29
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Int8Array"                                 988.12 %        *** 8.782491e-30
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Uint16Array"                               987.60 %        *** 8.585867e-27
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Uint32Array"                               981.23 %        *** 2.542324e-29
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Uint8Array"                                  2.99 %            2.962923e-01
 assert/deepequal-typedarrays.js len=1000000 method="notDeepEqual" n=1 type="Uint8ClampedArray"                         982.95 %        *** 2.418260e-27
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Float32Array"                          4.20 %            6.680757e-02
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Float64Array"                          1.02 %            7.778071e-01
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Int16Array"                            5.87 %         ** 7.262476e-03
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Int32Array"                            6.40 %            9.935904e-02
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Int8Array"                             5.51 %          * 1.328911e-02
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Uint16Array"                           5.81 %         ** 8.281852e-03
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Uint32Array"                           7.68 %         ** 1.617419e-03
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Uint8Array"                           -1.32 %            4.273639e-01
 assert/deepequal-typedarrays.js len=1000000 method="notDeepStrictEqual" n=1 type="Uint8ClampedArray"                     4.02 %          * 4.113977e-02
 assert/throws.js method="doesNotThrow RegExp" n=1000000                                                                261.80 %        *** 6.572196e-24
 assert/throws.js method="doesNotThrow TypeError" n=1000000                                                             571.93 %        *** 8.693018e-27
 assert/throws.js method="doesNotThrow" n=1000000                                                                       127.76 %        *** 4.291609e-22
 assert/throws.js method="throws RegExp" n=1000000                                                                        1.50 %         ** 3.911706e-03
 assert/throws.js method="throws TypeError" n=1000000                                                                     8.39 %        *** 5.176500e-09
 assert/throws.js method="throws" n=1000000                                                                               2.41 %        *** 2.203446e-08

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

assert

@nodejs-github-bot nodejs-github-bot added assert Issues and PRs related to the assert subsystem. errors Issues and PRs related to JavaScript errors originated in Node.js core. labels Jun 28, 2017
@BridgeAR BridgeAR force-pushed the improve-assert-performance branch from f72aa63 to b8451b0 Compare June 28, 2017 23:48
var i;

// Creates new array to avoid loop invariant code motion
switch (conf.method) {
case 'strict':
case 'deepEqual':
bench.start();
for (i = 0; i < n; ++i) {
// eslint-disable-next-line no-restricted-properties
assert.deepEqual([actual], [expected]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not do

const tesee = assert[conf.method];

Instead of the whole switch?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, the values do change at least partly so we can't just remove the switch. I can combine the ones that have the same arguments if you want me to.

Copy link
Contributor

Choose a reason for hiding this comment

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

Im ±0, your call.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think I prefer to stick to the way it is as that way it's simpler to add more tests for the same function with different inputs.

@@ -423,8 +423,7 @@ assert.throws(makeBlock(thrower, TypeError));
assert.ok(e instanceof TypeError, 'type');
}
assert.strictEqual(true, threw,
'a.throws with an explicit error is eating extra errors',
a.AssertionError);
'a.throws with an explicit error is eating extra errors');
Copy link
Contributor

Choose a reason for hiding this comment

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

😄
I'm gonna dig and find how did that happen. Probably an interesting story.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not much of a story, it has always been there, nobody notices for 8 years
4f679fd#diff-02063f30815b78f7986ee0c212140b8eR110

@refack refack self-assigned this Jun 28, 2017
@refack
Copy link
Contributor

refack commented Jun 28, 2017

Quick sanity: https://ci.nodejs.org/job/node-test-commit-linuxone/6915/
Look good, will review thoroughly...

@mscdex mscdex added the performance Issues and PRs related to the performance of Node.js. label Jun 29, 2017
@@ -1,39 +1,63 @@
'use strict';

Copy link
Member

Choose a reason for hiding this comment

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

nit: unnecessary whitespace changes

Copy link
Member Author

Choose a reason for hiding this comment

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

Is it preferred to not use a line break after use strict in general or would you just want to keep that as a separate concern?

@Trott
Copy link
Member

Trott commented Jun 29, 2017

Not a requirement for landing but helpful if someone has the inclination to run make coverage and report back: Until a few weeks ago, lib/assert.js had 100% test coverage. A refactoring resulted in it having almost 100% test coverage but not quite. It would be good to know if and how coverage stats will be changed with this PR.

@BridgeAR BridgeAR changed the title Improve assert performance assert: improve performance Jun 29, 2017
@BridgeAR
Copy link
Member Author

BridgeAR commented Jun 30, 2017

@Trott I checked the coverage and I was able to remove even more code paths and move another check further up. Now the coverage is back to 100%. So PTAL.
Using a non RegExp as second argument for assert.throws and assert.doesNotThrow resulted in a error before, so I changed that back to how it was before. If you would prefer something else instead: please let me know.

Those changes are reflected in these benchmarks:

 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="array"                    42.04 %        *** 6.843987e-44
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="boolean"                  43.57 %        *** 2.703836e-46
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="new-array"                39.97 %        *** 4.276696e-23
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="null"                     41.04 %        *** 2.034303e-23
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="number"                   42.44 %        *** 5.304838e-19
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="object"                   39.72 %        *** 3.588488e-19
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="string"                   52.18 %        *** 9.506625e-20
 assert/deepequal-prims-and-objs-big-array-set.js method="deepEqual Set" len=100000 n=25 prim="undefined"                41.51 %        *** 3.533457e-24
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="array"              40.82 %        *** 2.085361e-42
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="boolean"            43.76 %        *** 1.154195e-44
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="new-array"          40.94 %        *** 1.453874e-48
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="null"               42.73 %        *** 1.021447e-36
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="number"             46.04 %        *** 1.265156e-48
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="object"             40.66 %        *** 1.752583e-48
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="string"             63.83 %        *** 1.722373e-14
 assert/deepequal-prims-and-objs-big-array-set.js method="deepStrictEqual Set" len=100000 n=25 prim="undefined"          42.05 %        *** 7.665409e-30
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="array"                 46.48 %        *** 1.125309e-42
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="boolean"               47.13 %        *** 1.913099e-42
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="new-array"             44.68 %        *** 6.298514e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="null"                  51.42 %        *** 8.369991e-32
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="number"                49.55 %        *** 5.140566e-41
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="object"                46.88 %        *** 5.781679e-39
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="string"                56.48 %        *** 6.461916e-20
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepEqual Set" len=100000 n=25 prim="undefined"             50.79 %        *** 3.532599e-27
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="array"           44.91 %        *** 1.921818e-39
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="boolean"         45.89 %        *** 1.467412e-25
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="new-array"       44.31 %        *** 1.076166e-20
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="null"            45.83 %        *** 9.819397e-26
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="number"          46.78 %        *** 4.519398e-24
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="object"          45.23 %        *** 2.189934e-28
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="string"          54.66 %        *** 4.675293e-26
 assert/deepequal-prims-and-objs-big-array-set.js method="notDeepStrictEqual Set" len=100000 n=25 prim="undefined"       58.71 %        *** 5.609204e-24
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="array"                                    1.36 %          * 4.094796e-02
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="boolean"                                 -0.37 %            6.079521e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="new-array"                                1.29 %            1.181016e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="null"                                     0.74 %            2.758807e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="number"                                   0.78 %            2.118160e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="object"                                   1.69 %          * 1.241283e-02
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="string"                                   0.47 %            5.299881e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepEqual" n=1000000 prim="undefined"                                0.41 %            5.487362e-01
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="array"                              9.36 %        *** 2.970686e-18
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="boolean"                            8.65 %        *** 1.500166e-13
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="new-array"                          9.52 %        *** 4.877225e-18
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="null"                              10.33 %        *** 7.432987e-19
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="number"                            10.77 %        *** 9.287721e-20
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="object"                            10.81 %        *** 1.189148e-20
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="string"                            10.00 %        *** 3.991182e-16
 assert/deepequal-prims-and-objs-big-loop.js method="deepStrictEqual" n=1000000 prim="undefined"                         10.00 %        *** 1.348992e-18
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="array"                                30.07 %        *** 8.674371e-34
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="boolean"                               1.30 %            8.945766e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="new-array"                            32.55 %        *** 3.999601e-34
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="null"                                  1.24 %            5.040777e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="number"                                0.85 %            2.250620e-01
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="object"                               28.79 %        *** 9.978597e-36
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="string"                                0.62 %            3.536732e-01
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepEqual" n=1000000 prim="undefined"                             1.41 %          * 4.266881e-02
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="array"                          23.41 %        *** 9.407808e-29
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="boolean"                         9.44 %        *** 1.786321e-14
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="new-array"                      23.30 %        *** 8.095747e-38
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="null"                           11.15 %        *** 6.224962e-24
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="number"                         10.23 %        *** 8.406336e-23
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="object"                         22.63 %        *** 1.001633e-34
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="string"                         10.89 %        *** 6.040105e-19
 assert/deepequal-prims-and-objs-big-loop.js method="notDeepStrictEqual" n=1000000 prim="undefined"                       9.79 %        *** 3.325113e-17

[refack: folded benchmark results]

const bench = common.createBenchmark(main, {
n: [1e3],
n: [1e5],
Copy link
Member

Choose a reason for hiding this comment

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

@mscdex @nodejs/benchmarking Is this sort of benchmark change OK? Do we usually do changes like this, or do we more typically add additional cases (so n: [1e3, 1e5])?

Copy link
Contributor

@refack refack Jun 30, 2017

Choose a reason for hiding this comment

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

Also IMHO even 1e5 is too low for a CPU bound op.
(Some of the p values are too high)

Copy link
Member

Choose a reason for hiding this comment

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

I'd be tempted to suggest adding as an extra - unless something has been found to be not valid with it being 1e3.
@joyeecheung implemented this benchmark in the first place, was there any particular reason for choosing 1e3 and not a larger number?
The other thing to consider is the length of time to run the benchmark, we should be careful about adding more variants which would add to longer run times for the benchmark suite

Copy link
Member Author

@BridgeAR BridgeAR Jun 30, 2017

Choose a reason for hiding this comment

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

Using different n is not really useful as far as I can tell. And as @refack pointed out using 1e5 is still a low value. Otherwise it's difficult to get a higher significance if I'm correct.

@refack
Copy link
Contributor

refack commented Jun 30, 2017

@BridgeAR
Copy link
Member Author

I stumbled open a few more tiny improvements (tiny buffers and different sized buffers are checked faster now) and turbofan still can't handle try catch well.

lib/assert.js Outdated
}
if (len < 300) {
var offset = 0;
while (offset < len) {
Copy link
Contributor

Choose a reason for hiding this comment

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

why not for?

Copy link
Member Author

Choose a reason for hiding this comment

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

shrug

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

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

% /benchmark/ changes decision

lib/assert.js Outdated
}
return true;
}
} else if (isArguments(actualTag) || isArguments(expectedTag)) {
Copy link
Member

Choose a reason for hiding this comment

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

This is a special case for compatibility so the link to the original PR should be kept IMO

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

lib/assert.js Outdated
return false;
}
if (isObjectOrArrayTag(actualTag)) {
return;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe a comment about returning undefined means we need to check further?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

method: [
'doesNotThrow',
'throws',
'throws TypeError',
Copy link
Member

Choose a reason for hiding this comment

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

Maybe get rid of the space in the argument values

Copy link
Member Author

Choose a reason for hiding this comment

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

Would be a underscore be fine instead? The first part is the function name and that's why I'd like some kind of distinction.

@refack
Copy link
Contributor

refack commented Jul 2, 2017

Pre-land CI: https://ci.nodejs.org/job/node-test-commit/10890/
(Will land without the changes to /benchmark/)

Copy link
Member

@benjamingr benjamingr left a comment

Choose a reason for hiding this comment

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

Actual changes LGTM and make a nice improvement - since it changes a lot of code a CITGM run would also be appreciated.

@refack
Copy link
Contributor

refack commented Jul 4, 2017

CITGM (Base): https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/897/
CITGM (PR): https://ci.nodejs.org/view/Node.js-citgm/job/citgm-smoker/898/

@refack
Copy link
Contributor

refack commented Jul 8, 2017

@BridgeAR I tried to resolve the conflicts, but it's too delicate. So please rebase.

BridgeAR added 3 commits July 8, 2017 21:57
The benchmarks had the strict and non strict labels switched.
This is fixed and the benchmarks were extended to check more
possible input types and function calls.
The lazy loading is not needed as the errors themself lazy
load assert. Therefore the circle is working as intended
even without this lazy loading.

Improve Array, object, ArrayBuffer, Set and Map performance
in all deepEqual checks by removing unecessary code paths and
by moving expensive checks further back.

Improve throws and doesNotThrow performance by removing dead
code and simplifying the overall logic.
assert.strictEqual can either have two or three arguments, not four.
@BridgeAR BridgeAR force-pushed the improve-assert-performance branch from 83a6d77 to 6e456f1 Compare July 8, 2017 20:43
@BridgeAR
Copy link
Member Author

BridgeAR commented Jul 8, 2017

Rebased

@refack
Copy link
Contributor

refack commented Jul 8, 2017

refack pushed a commit to refack/node that referenced this pull request Jul 9, 2017
The lazy loading is not needed as the errors themself lazy
load assert. Therefore the circle is working as intended
even without this lazy loading.

Improve Array, object, ArrayBuffer, Set and Map performance
in all deepEqual checks by removing unecessary code paths and
by moving expensive checks further back.

Improve throws and doesNotThrow performance by removing dead
code and simplifying the overall logic.

PR-URL: nodejs#13973
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
@refack
Copy link
Contributor

refack commented Jul 9, 2017

Landed in be20e9e without the benchamrk changes.
@BridgeAR you should open a PR just for that

@addaleax
Copy link
Member

@refack Just for context, what’s the motivation for leaving out benchmarks?

Anyway, if anything in here can be backported to v8.x, it would need to be backported manually (guide).

We’re already in a situation where a lot of changes to assert depend on semver-major changes, so any work to reduce the delta would be really appreciated.

@refack
Copy link
Contributor

refack commented Jul 22, 2017

@refack Just for context, what’s the motivation for leaving out benchmarks?

They were done in this PR to prove it actually has a positive performance gain, but It would perturb https://benchmarking.nodejs.org/ so we spun off #14147 to be discussed just in the context of benchmarking changes.

@refack
Copy link
Contributor

refack commented Jul 22, 2017

P.S. should probably land with #14258

@BridgeAR
Copy link
Member Author

@addaleax I am going to backport this later on.

@addaleax
Copy link
Member

Lands cleanly now :)

addaleax pushed a commit that referenced this pull request Jul 28, 2017
The lazy loading is not needed as the errors themself lazy
load assert. Therefore the circle is working as intended
even without this lazy loading.

Improve Array, object, ArrayBuffer, Set and Map performance
in all deepEqual checks by removing unecessary code paths and
by moving expensive checks further back.

Improve throws and doesNotThrow performance by removing dead
code and simplifying the overall logic.

PR-URL: #13973
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
@addaleax addaleax mentioned this pull request Aug 2, 2017
refack pushed a commit that referenced this pull request Aug 13, 2017
The benchmarks had the strict and non strict labels switched.
This is fixed and the benchmarks were extended to check more
possible input types and function calls.

PR-URL: #14147
Refs: #13973
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
addaleax pushed a commit that referenced this pull request Aug 13, 2017
The benchmarks had the strict and non strict labels switched.
This is fixed and the benchmarks were extended to check more
possible input types and function calls.

PR-URL: #14147
Refs: #13973
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
@refack refack removed their assignment Oct 20, 2018
@BridgeAR BridgeAR deleted the improve-assert-performance branch April 1, 2019 23:36
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. errors Issues and PRs related to JavaScript errors originated in Node.js core. performance Issues and PRs related to the performance of Node.js.
Projects
None yet
Development

Successfully merging this pull request may close these issues.