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

util: simplify constructor retrieval in inspect() #36466

Merged
merged 1 commit into from Dec 14, 2020

Conversation

Trott
Copy link
Member

@Trott Trott commented Dec 10, 2020

Instead of looping through a list of typed arrays, use
TypedArrayPrototypeGetSymbolToStringTag.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • commit message follows commit guidelines

@nodejs-github-bot nodejs-github-bot added the util Issues and PRs related to the built-in util module. label Dec 10, 2020
@Trott Trott added the request-ci Add this label to start a Jenkins CI on a PR. label Dec 10, 2020
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Dec 10, 2020
@nodejs-github-bot
Copy link
Collaborator

@Trott Trott requested a review from BridgeAR December 10, 2020 13:10
Comment on lines 832 to +842
let fallback = '';
if (constructor === null) {
const constr = findTypedConstructor(value);
fallback = constr.name;
fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably use:

Suggested change
let fallback = '';
if (constructor === null) {
const constr = findTypedConstructor(value);
fallback = constr.name;
fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
const fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
if (constructor === null) {

So that fallback is always non‑empty.

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 the idea originally was to avoid the overhead of a function call where possible. Judging from our test coverage stats, constructor being null is the unusual case (616 times hitting the if but only 33 times evaluating to true).

The performance difference seems likely to be unmeasurable and the code simplification may very well be worth it. But I'd prefer that be handled in a separate pull request. I'd prefer that this pull request preserve the code shape and merely replace/eliminate the existing function.

This is reminding me to run benchmarks for this change.

Copy link
Contributor

@ExE-Boss ExE-Boss Dec 10, 2020

Choose a reason for hiding this comment

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

Well, TypedArrayPrototypeGetSymbolToStringTag is already invoked by isTypedArray:

function isTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== undefined;
}


It should be possible to reduce this to always perform only one TypedArrayPrototypeGetSymbolToStringTag call, even in the constructor === null case, but that is probably overkill:

   if (value[SymbolIterator] || constructor === null) {
     noIterator = false;
+    let typedArrayName;
     if (ArrayIsArray(value)) {
-    } else if (isTypedArray(name)) {
+    } else if ((typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value)) !== undefined) {
       keys = getOwnNonIndexProperties(value, filter);
       let bound = value;
-      let fallback = '';
       if (constructor === null) {
-        fallback = TypedArrayPrototypeGetSymbolToStringTag(value);
         // Reconstruct the array information.
-        bound = new primordials[primordials](value);
+        bound = new primordials[typedArrayName](value);
       }
       const size = TypedArrayPrototypeGetLength(value);
-      const prefix = getPrefix(constructor, tag, fallback, `(${size})`);
+      const prefix = getPrefix(constructor, tag, typedArrayName, `(${size})`);

@Trott
Copy link
Member Author

Trott commented Dec 10, 2020

@Trott
Copy link
Member Author

Trott commented Dec 11, 2020

Benchmark results seem OK:

15:25:18  util/inspect.js option='colors' method='Date' n=20000                          *     -5.88 %       ±4.69% ±6.26%  ±8.21%
15:25:18  util/inspect.js option='none' method='Object_deep_ln' n=20000                 **     -3.26 %       ±2.29% ±3.05%  ±3.97%
15:25:18  util/inspect.js option='none' method='Object_empty' n=20000                    *      4.28 %       ±3.82% ±5.10%  ±6.67%

15:25:18 Be aware that when doing many comparisons the risk of a false-positive
15:25:18 result increases. In this case there are 51 comparisons, you can thus
15:25:18 expect the following amount of false-positive results:
15:25:18   2.55 false positives, when considering a   5% risk acceptance (*, **, ***),
15:25:18   0.51 false positives, when considering a   1% risk acceptance (**, ***),
15:25:18   0.05 false positives, when considering a 0.1% risk acceptance (***)
15:25:18                                                                        confidence improvement accuracy (*)   (**)   (***)
15:25:18  util/inspect-array.js type='denseArray' len=100000 n=500                              0.67 %       ±5.34% ±7.11%  ±9.27%
15:25:18  util/inspect-array.js type='denseArray' len=100 n=500                                 1.13 %       ±3.89% ±5.18%  ±6.75%
15:25:18  util/inspect-array.js type='denseArray_showHidden' len=100000 n=500                   0.83 %       ±4.61% ±6.13%  ±7.98%
15:25:18  util/inspect-array.js type='denseArray_showHidden' len=100 n=500                      1.31 %       ±3.81% ±5.07%  ±6.60%
15:25:18  util/inspect-array.js type='mixedArray' len=100000 n=500                             -0.05 %       ±2.47% ±3.29%  ±4.28%
15:25:18  util/inspect-array.js type='mixedArray' len=100 n=500                                 1.01 %       ±3.89% ±5.18%  ±6.74%
15:25:18  util/inspect-array.js type='sparseArray' len=100000 n=500                            -0.15 %       ±4.16% ±5.53%  ±7.20%
15:25:18  util/inspect-array.js type='sparseArray' len=100 n=500                                1.18 %       ±4.34% ±5.79%  ±7.56%
15:25:18  util/inspect.js option='colors' method='Array' n=20000                                0.61 %       ±2.10% ±2.80%  ±3.64%
15:25:18  util/inspect.js option='colors' method='Date' n=20000                          *     -5.88 %       ±4.69% ±6.26%  ±8.21%
15:25:18  util/inspect.js option='colors' method='Error' n=20000                               -1.18 %       ±3.79% ±5.04%  ±6.57%
15:25:18  util/inspect.js option='colors' method='Number' n=20000                              -1.30 %       ±3.98% ±5.31%  ±6.93%
15:25:18  util/inspect.js option='colors' method='Object_deep_ln' n=20000                       0.58 %       ±1.67% ±2.23%  ±2.90%
15:25:18  util/inspect.js option='colors' method='Object_empty' n=20000                         0.53 %       ±4.28% ±5.70%  ±7.41%
15:25:18  util/inspect.js option='colors' method='Object' n=20000                               1.21 %       ±3.56% ±4.74%  ±6.17%
15:25:18  util/inspect.js option='colors' method='Set' n=20000                                 -3.47 %       ±4.67% ±6.22%  ±8.10%
15:25:18  util/inspect.js option='colors' method='String_boxed' n=20000                         0.08 %       ±4.51% ±6.00%  ±7.82%
15:25:18  util/inspect.js option='colors' method='String_complex' n=20000                       1.16 %       ±4.39% ±5.83%  ±7.59%
15:25:18  util/inspect.js option='colors' method='String' n=20000                               0.67 %       ±4.67% ±6.21%  ±8.10%
15:25:18  util/inspect.js option='colors' method='TypedArray_extra' n=20000                     1.33 %       ±2.18% ±2.90%  ±3.77%
15:25:18  util/inspect.js option='colors' method='TypedArray' n=20000                           1.12 %       ±1.87% ±2.49%  ±3.24%
15:25:18  util/inspect.js option='none' method='Array' n=20000                                  2.63 %       ±6.13% ±8.19% ±10.71%
15:25:18  util/inspect.js option='none' method='Date' n=20000                                  -3.11 %       ±4.32% ±5.76%  ±7.50%
15:25:18  util/inspect.js option='none' method='Error' n=20000                                 -0.57 %       ±3.73% ±4.96%  ±6.45%
15:25:18  util/inspect.js option='none' method='Number' n=20000                                 0.99 %       ±3.42% ±4.55%  ±5.92%
15:25:18  util/inspect.js option='none' method='Object_deep_ln' n=20000                 **     -3.26 %       ±2.29% ±3.05%  ±3.97%
15:25:18  util/inspect.js option='none' method='Object_empty' n=20000                    *      4.28 %       ±3.82% ±5.10%  ±6.67%
15:25:18  util/inspect.js option='none' method='Object' n=20000                                 2.62 %       ±5.11% ±6.80%  ±8.86%
15:25:18  util/inspect.js option='none' method='Set' n=20000                                   -2.91 %       ±4.79% ±6.38%  ±8.31%
15:25:18  util/inspect.js option='none' method='String_boxed' n=20000                          -2.02 %       ±3.95% ±5.27%  ±6.89%
15:25:18  util/inspect.js option='none' method='String_complex' n=20000                         1.76 %       ±5.12% ±6.82%  ±8.87%
15:25:18  util/inspect.js option='none' method='String' n=20000                                -2.11 %       ±4.35% ±5.79%  ±7.54%
15:25:18  util/inspect.js option='none' method='TypedArray_extra' n=20000                      -3.93 %       ±6.05% ±8.14% ±10.78%
15:25:18  util/inspect.js option='none' method='TypedArray' n=20000                            -2.44 %       ±4.85% ±6.51%  ±8.61%
15:25:18  util/inspect.js option='showHidden' method='Array' n=20000                           -0.67 %       ±4.44% ±5.96%  ±7.88%
15:25:18  util/inspect.js option='showHidden' method='Date' n=20000                            -2.07 %       ±4.13% ±5.51%  ±7.20%
15:25:18  util/inspect.js option='showHidden' method='Error' n=20000                           -2.60 %       ±3.77% ±5.04%  ±6.60%
15:25:18  util/inspect.js option='showHidden' method='Number' n=20000                           0.55 %       ±4.56% ±6.06%  ±7.90%
15:25:18  util/inspect.js option='showHidden' method='Object_deep_ln' n=20000                  -0.64 %       ±2.50% ±3.33%  ±4.34%
15:25:18  util/inspect.js option='showHidden' method='Object_empty' n=20000                     1.53 %       ±4.64% ±6.18%  ±8.06%
15:25:18  util/inspect.js option='showHidden' method='Object' n=20000                          -1.09 %       ±4.44% ±5.91%  ±7.70%
15:25:18  util/inspect.js option='showHidden' method='Set' n=20000                              1.38 %       ±5.30% ±7.05%  ±9.18%
15:25:18  util/inspect.js option='showHidden' method='String_boxed' n=20000                     1.11 %       ±3.77% ±5.02%  ±6.54%
15:25:18  util/inspect.js option='showHidden' method='String_complex' n=20000                  -0.27 %       ±4.27% ±5.68%  ±7.39%
15:25:18  util/inspect.js option='showHidden' method='String' n=20000                          -3.13 %       ±3.14% ±4.18%  ±5.44%
15:25:18  util/inspect.js option='showHidden' method='TypedArray_extra' n=20000                -0.59 %       ±2.55% ±3.41%  ±4.45%
15:25:18  util/inspect.js option='showHidden' method='TypedArray' n=20000                       0.83 %       ±2.14% ±2.85%  ±3.71%
15:25:18  util/inspect-proxy.js isProxy=0 showProxy=0 n=100000                                 -1.60 %       ±3.81% ±5.11%  ±6.72%
15:25:18  util/inspect-proxy.js isProxy=0 showProxy=1 n=100000                                  0.90 %       ±1.58% ±2.11%  ±2.75%
15:25:18  util/inspect-proxy.js isProxy=1 showProxy=0 n=100000                                 -0.70 %       ±2.52% ±3.36%  ±4.38%
15:25:18  util/inspect-proxy.js isProxy=1 showProxy=1 n=100000                                  1.51 %       ±2.50% ±3.35%  ±4.39%
15:25:18 
15:25:18 Be aware that when doing many comparisons the risk of a false-positive
15:25:18 result increases. In this case there are 51 comparisons, you can thus
15:25:18 expect the following amount of false-positive results:
15:25:18   2.55 false positives, when considering a   5% risk acceptance (*, **, ***),
15:25:18   0.51 false positives, when considering a   1% risk acceptance (**, ***),
15:25:18   0.05 false positives, when considering a 0.1% risk acceptance (***)

Instead of looping through a list of typed arrays, use
TypedArrayPrototypeGetSymbolToStringTag.

PR-URL: nodejs#36466
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
@Trott
Copy link
Member Author

Trott commented Dec 14, 2020

Landed in f43d1ca

@Trott Trott merged commit f43d1ca into nodejs:master Dec 14, 2020
@Trott Trott deleted the simplify-inspect branch December 14, 2020 13:43
targos pushed a commit that referenced this pull request Dec 21, 2020
Instead of looping through a list of typed arrays, use
TypedArrayPrototypeGetSymbolToStringTag.

PR-URL: #36466
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request May 16, 2021
Instead of looping through a list of typed arrays, use
TypedArrayPrototypeGetSymbolToStringTag.

PR-URL: #36466
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
targos pushed a commit that referenced this pull request Jun 11, 2021
Instead of looping through a list of typed arrays, use
TypedArrayPrototypeGetSymbolToStringTag.

PR-URL: #36466
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
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

8 participants