Repository: nodejs/node
Pull request: timers: optimize timer functions with improved argument handling

After:

```sh
timers/immediate.js
timers/immediate.js type="depth" n=5000000: 80,080.39740943641
timers/immediate.js type="depth1" n=5000000: 81,172.49117847806
timers/immediate.js type="breadth" n=5000000: 6,043,891.345759598
timers/immediate.js type="breadth1" n=5000000: 3,625,307.3296283777
timers/immediate.js type="breadth4" n=5000000: 3,390,438.1071638097
timers/immediate.js type="clear" n=5000000: 17,872,894.015227303

timers/set-immediate-breadth-args.js
timers/set-immediate-breadth-args.js n=5000000: 2,719,426.8722150475

timers/set-immediate-breadth.js
timers/set-immediate-breadth.js n=10000000: 5,408,182.94584942

timers/set-immediate-depth-args.js
timers/set-immediate-depth-args.js n=5000000: 81,470.89492708661

timers/timers-breadth-args.js
timers/timers-breadth-args.js n=1000000: 2,293,034.7427874957

timers/timers-breadth.js
timers/timers-breadth.js n=5000000: 3,560,692.234861032

timers/timers-cancel-pooled.js
timers/timers-cancel-pooled.js n=5000000: 26,070,668.11238602

timers/timers-cancel-unpooled.js
timers/timers-cancel-unpooled.js direction="start" n=1000000: 4,025,027.621752054
timers/timers-cancel-unpooled.js direction="end" n=1000000: 23,885,540.68014507

timers/timers-depth.js
timers/timers-depth.js n=1000: 871.7480297332925

timers/timers-insert-pooled.js
timers/timers-insert-pooled.js n=5000000: 3,114,655.0450797137

timers/timers-insert-unpooled.js
timers/timers-insert-unpooled.js direction="start" n=1000000: 3,866,726.810766608
timers/timers-insert-unpooled.js direction="end" n=1000000: 2,321,271.5229021

timers/timers-timeout-nexttick.js
timers/timers-timeout-nexttick.js n=50000: 3,159,308.1115235765
timers/timers-timeout-nexttick.js n=5000000: 6,083,459.279596363

timers/timers-timeout-pooled.js
timers/timers-timeout-pooled.js n=10000000: 18,978,540.19786525

timers/timers-timeout-unpooled.js
timers/timers-timeout-unpooled.js n=1000000: 18,657,978.268119812
```

Before:

```sh
gurgunday@Gurguns-MacBook-Air node % node benchmark/run.js timers              

timers/immediate.js
timers/immediate.js type="depth" n=5000000: 78,882.93004449889
timers/immediate.js type="depth1" n=5000000: 79,208.86810881029
timers/immediate.js type="breadth" n=5000000: 5,475,245.614097755
timers/immediate.js type="breadth1" n=5000000: 3,418,192.2343457905
timers/immediate.js type="breadth4" n=5000000: 2,220,066.291179455
timers/immediate.js type="clear" n=5000000: 16,625,836.383481566

timers/set-immediate-breadth-args.js
timers/set-immediate-breadth-args.js n=5000000: 2,484,761.063515046

timers/set-immediate-breadth.js
timers/set-immediate-breadth.js n=10000000: 5,217,361.020062365

timers/set-immediate-depth-args.js
timers/set-immediate-depth-args.js n=5000000: 78,881.00406705718

timers/timers-breadth-args.js
timers/timers-breadth-args.js n=1000000: 2,320,253.8066240572

timers/timers-breadth.js
timers/timers-breadth.js n=5000000: 3,627,726.0207083295

timers/timers-cancel-pooled.js
timers/timers-cancel-pooled.js n=5000000: 28,413,416.044484362

timers/timers-cancel-unpooled.js
timers/timers-cancel-unpooled.js direction="start" n=1000000: 3,928,022.9082296006
timers/timers-cancel-unpooled.js direction="end" n=1000000: 22,356,256.425188098

timers/timers-depth.js
timers/timers-depth.js n=1000: 871.8493679691478

timers/timers-insert-pooled.js
timers/timers-insert-pooled.js n=5000000: 2,885,978.1773654805

timers/timers-insert-unpooled.js
timers/timers-insert-unpooled.js direction="start" n=1000000: 3,951,745.894772246
timers/timers-insert-unpooled.js direction="end" n=1000000: 2,249,549.459109555

timers/timers-timeout-nexttick.js
timers/timers-timeout-nexttick.js n=50000: 3,015,908.91955063
timers/timers-timeout-nexttick.js n=5000000: 6,165,632.315873412

timers/timers-timeout-pooled.js
timers/timers-timeout-pooled.js n=10000000: 16,896,694.03508683

timers/timers-timeout-unpooled.js
timers/timers-timeout-unpooled.js n=1000000: 16,643,169.56249218
```

Changed files:
filename: lib/timers.js
patch: @@ -22,7 +22,6 @@
 'use strict';
 
 const {
-  ArrayPrototypePush,
   MathTrunc,
   ObjectDefineProperties,
   ObjectDefineProperty,
@@ -113,38 +112,13 @@ function unenroll(item) {
  * after `after` milliseconds.
  * @param {Function} callback
  * @param {number} [after]
- * @param {any} [arg1]
- * @param {any} [arg2]
- * @param {any} [arg3]
+ * @param {...any} [args]
  * @returns {Timeout}
  */
-function setTimeout(callback, after, arg1, arg2, arg3) {
+function setTimeout(callback, after, ...args) {
   validateFunction(callback, 'callback');
-
-  let i, args;
-  switch (arguments.length) {
-    // fast cases
-    case 1:
-    case 2:
-      break;
-    case 3:
-      args = [arg1];
-      break;
-    case 4:
-      args = [arg1, arg2];
-      break;
-    default:
-      args = [arg1, arg2, arg3];
-      for (i = 5; i < arguments.length; i++) {
-        // Extend array dynamically, makes .apply run much faster in v6.0.0
-        ArrayPrototypePush(args, arguments[i]);
-      }
-      break;
-  }
-
-  const timeout = new Timeout(callback, after, args, false, true);
+  const timeout = new Timeout(callback, after, args.length ? args : undefined, false, true);
   insert(timeout, timeout._idleTimeout);
-
   return timeout;
 }
 
@@ -182,38 +156,13 @@ function clearTimeout(timer) {
  * every `repeat` milliseconds.
  * @param {Function} callback
  * @param {number} [repeat]
- * @param {any} [arg1]
- * @param {any} [arg2]
- * @param {any} [arg3]
+ * @param {...any} [args]
  * @returns {Timeout}
  */
-function setInterval(callback, repeat, arg1, arg2, arg3) {
+function setInterval(callback, repeat, ...args) {
   validateFunction(callback, 'callback');
-
-  let i, args;
-  switch (arguments.length) {
-    // fast cases
-    case 1:
-    case 2:
-      break;
-    case 3:
-      args = [arg1];
-      break;
-    case 4:
-      args = [arg1, arg2];
-      break;
-    default:
-      args = [arg1, arg2, arg3];
-      for (i = 5; i < arguments.length; i++) {
-        // Extend array dynamically, makes .apply run much faster in v6.0.0
-        ArrayPrototypePush(args, arguments[i]);
-      }
-      break;
-  }
-
-  const timeout = new Timeout(callback, repeat, args, true, true);
+  const timeout = new Timeout(callback, repeat, args.length ? args : undefined, true, true);
   insert(timeout, timeout._idleTimeout);
-
   return timeout;
 }
 
@@ -255,35 +204,12 @@ Timeout.prototype[SymbolToPrimitive] = function() {
  * Schedules the immediate execution of `callback`
  * after I/O events' callbacks.
  * @param {Function} callback
- * @param {any} [arg1]
- * @param {any} [arg2]
- * @param {any} [arg3]
+ * @param {...any} [args]
  * @returns {Immediate}
  */
-function setImmediate(callback, arg1, arg2, arg3) {
+function setImmediate(callback, ...args) {
   validateFunction(callback, 'callback');
-
-  let i, args;
-  switch (arguments.length) {
-    // fast cases
-    case 1:
-      break;
-    case 2:
-      args = [arg1];
-      break;
-    case 3:
-      args = [arg1, arg2];
-      break;
-    default:
-      args = [arg1, arg2, arg3];
-      for (i = 4; i < arguments.length; i++) {
-        // Extend array dynamically, makes .apply run much faster in v6.0.0
-        ArrayPrototypePush(args, arguments[i]);
-      }
-      break;
-  }
-
-  return new Immediate(callback, args);
+  return new Immediate(callback, args.length ? args : undefined);
 }
 
 ObjectDefineProperty(setImmediate, customPromisify, {