Skip to content

timers: allow timers to be used as primitives

This allows timers to be matched to numeric Ids and therefore used as keys of an Object, passed and stored without storing the Timer instance.

clearTimeout/clearInterval is modified to support numeric/string Ids.

Co-authored-by: Bradley Farias bradley.meck@gmail.com Co-authored-by: Anatoli Papirovski apapirovski@mac.com

Refs: https://github.com/nodejs/node/pull/21152

Continuing great work of @bmeck and @apapirovski. Noticed this PR, checked the benchmarks and they looked just fine with almost no impact now. See results on my machine below

Object.create(null) benchmark

 ➔ dev/node/node cat compare-timer-obj-str.csv | Rscript benchmark/compare.R                                                 

                                                              confidence improvement accuracy (*)    (**)   (***)
 timers/immediate.js type='breadth' n=5000000                                -1.21 %       ±3.23%  ±4.33%  ±5.69%
 timers/immediate.js type='breadth1' n=5000000                               -1.80 %       ±4.25%  ±5.69%  ±7.49%
 timers/immediate.js type='breadth4' n=5000000                               -3.73 %       ±6.41%  ±8.58% ±11.29%
 timers/immediate.js type='clear' n=5000000                            *     -4.99 %       ±4.69%  ±6.28%  ±8.26%
 timers/immediate.js type='depth' n=5000000                                  -0.45 %       ±3.93%  ±5.26%  ±6.92%
 timers/immediate.js type='depth1' n=5000000                                 -2.77 %       ±3.01%  ±4.03%  ±5.31%
 timers/set-immediate-breadth-args.js n=5000000                               1.00 %       ±3.88%  ±5.19%  ±6.83%
 timers/set-immediate-breadth.js n=10000000                                   2.76 %       ±4.35%  ±5.83%  ±7.68%
 timers/set-immediate-depth-args.js n=5000000                                -1.65 %       ±4.92%  ±6.60%  ±8.69%
 timers/timers-breadth-args.js n=1000000                                     -0.01 %       ±6.71%  ±9.00% ±11.85%
 timers/timers-breadth.js n=5000000                                          -0.95 %       ±5.75%  ±7.70% ±10.13%
 timers/timers-cancel-pooled.js n=5000000                                     3.28 %       ±9.96% ±13.34% ±17.54%
 timers/timers-cancel-unpooled.js direction='end' n=1000000                   4.13 %       ±9.31% ±12.48% ±16.44%
 timers/timers-cancel-unpooled.js direction='start' n=1000000                -1.79 %       ±7.95% ±10.66% ±14.05%
 timers/timers-depth.js n=1000                                                0.28 %       ±1.24%  ±1.66%  ±2.20%
 timers/timers-insert-pooled.js n=5000000                                    -0.01 %       ±3.06%  ±4.10%  ±5.39%
 timers/timers-insert-unpooled.js direction='end' n=1000000                  -0.19 %       ±1.38%  ±1.84%  ±2.43%
 timers/timers-insert-unpooled.js direction='start' n=1000000                 0.21 %       ±2.11%  ±2.83%  ±3.72%
 timers/timers-timeout-nexttick.js n=50000                                   -6.10 %       ±8.16% ±10.95% ±14.44%
 timers/timers-timeout-nexttick.js n=5000000                                 -1.78 %       ±4.68%  ±6.27%  ±8.25%
 timers/timers-timeout-pooled.js n=10000000                                   0.50 %       ±5.02%  ±6.73%  ±8.85%
 timers/timers-timeout-unpooled.js n=1000000                                  3.26 %       ±9.15% ±12.28% ±16.18%

I've also tried to use Map and it show slightly worse performance for some reason.

Map benchmark

 ➔ dev/node/node cat compare-timer-map-str.csv | Rscript benchmark/compare.R                                                

                                                              confidence improvement accuracy (*)   (**)  (***)
 timers/immediate.js type='breadth' n=5000000                          *      2.40 %       ±1.97% ±2.65% ±3.49%
 timers/immediate.js type='breadth1' n=5000000                               -0.83 %       ±1.83% ±2.47% ±3.27%
 timers/immediate.js type='breadth4' n=5000000                               -2.01 %       ±3.36% ±4.50% ±5.93%
 timers/immediate.js type='clear' n=5000000                                  -0.82 %       ±2.74% ±3.68% ±4.85%
 timers/immediate.js type='depth' n=5000000                                   0.57 %       ±0.87% ±1.16% ±1.53%
 timers/immediate.js type='depth1' n=5000000                                 -0.12 %       ±1.40% ±1.89% ±2.50%
 timers/set-immediate-breadth-args.js n=5000000                              -0.76 %       ±1.72% ±2.32% ±3.08%
 timers/set-immediate-breadth.js n=10000000                                   0.53 %       ±4.10% ±5.49% ±7.22%
 timers/set-immediate-depth-args.js n=5000000                                 0.18 %       ±0.97% ±1.30% ±1.71%
 timers/timers-breadth-args.js n=1000000                               *     -4.43 %       ±3.39% ±4.55% ±5.98%
 timers/timers-breadth.js n=5000000                                          -1.42 %       ±2.95% ±3.96% ±5.20%
 timers/timers-cancel-pooled.js n=5000000                              *      2.81 %       ±2.70% ±3.62% ±4.77%
 timers/timers-cancel-unpooled.js direction='end' n=1000000            *     -2.91 %       ±2.71% ±3.65% ±4.86%
 timers/timers-cancel-unpooled.js direction='start' n=1000000         **     -4.62 %       ±2.64% ±3.54% ±4.66%
 timers/timers-depth.js n=1000                                               -0.06 %       ±0.87% ±1.16% ±1.53%
 timers/timers-insert-pooled.js n=5000000                                    -0.05 %       ±2.56% ±3.43% ±4.51%
 timers/timers-insert-unpooled.js direction='end' n=1000000                   0.05 %       ±1.92% ±2.57% ±3.38%
 timers/timers-insert-unpooled.js direction='start' n=1000000                -1.05 %       ±2.15% ±2.88% ±3.78%
 timers/timers-timeout-nexttick.js n=50000                                   -0.49 %       ±3.32% ±4.45% ±5.87%
 timers/timers-timeout-nexttick.js n=5000000                                  0.15 %       ±1.60% ±2.15% ±2.85%
 timers/timers-timeout-pooled.js n=10000000                            *     -1.22 %       ±1.20% ±1.62% ±2.14%
 timers/timers-timeout-unpooled.js n=1000000                           *     -4.14 %       ±3.23% ±4.34% ±5.74%

I didn't try the holey array as that would require using parseInt on passed strings to get the original number Id and could possibly add unnecessary overhead/unexpected errors to clearTimeout.

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

/cc @nodejs/timers

Merge request reports

Loading