node: improve performance of nextTick
authorTrevor Norris <trev.norris@gmail.com>
Fri, 27 Feb 2015 05:41:54 +0000 (22:41 -0700)
committerTrevor Norris <trev.norris@gmail.com>
Tue, 3 Mar 2015 20:45:19 +0000 (13:45 -0700)
Couple micro optimizations to improve performance of process.nextTick().
Removes ~60ns of execution time.

Also added small threshold to test that allows timer to fire early on
the order if microseconds.

PR-URL: https://github.com/iojs/io.js/pull/985
Reviewed-By: Vladimir Kurchatkin <vladimir.kurchatkin@gmail.com>
src/node.js
test/parallel/test-timers-first-fire.js

index a5a26e9..cf52cd1 100644 (file)
     function _tickCallback() {
       var callback, threw, tock;
 
-      scheduleMicrotasks();
-
-      while (tickInfo[kIndex] < tickInfo[kLength]) {
-        tock = nextTickQueue[tickInfo[kIndex]++];
-        callback = tock.callback;
-        threw = true;
-        try {
-          callback();
-          threw = false;
-        } finally {
-          if (threw)
+      do {
+        while (tickInfo[kIndex] < tickInfo[kLength]) {
+          tock = nextTickQueue[tickInfo[kIndex]++];
+          callback = tock.callback;
+          threw = true;
+          try {
+            callback();
+            threw = false;
+          } finally {
+            if (threw)
+              tickDone();
+          }
+          if (1e4 < tickInfo[kIndex])
             tickDone();
         }
-        if (1e4 < tickInfo[kIndex])
-          tickDone();
-      }
-
-      tickDone();
+        tickDone();
+        _runMicrotasks();
+        emitPendingUnhandledRejections();
+      } while (tickInfo[kLength] !== 0);
     }
 
     function _tickDomainCallback() {
       var callback, domain, threw, tock;
 
-      scheduleMicrotasks();
-
-      while (tickInfo[kIndex] < tickInfo[kLength]) {
-        tock = nextTickQueue[tickInfo[kIndex]++];
-        callback = tock.callback;
-        domain = tock.domain;
-        if (domain)
-          domain.enter();
-        threw = true;
-        try {
-          callback();
-          threw = false;
-        } finally {
-          if (threw)
+      do {
+        while (tickInfo[kIndex] < tickInfo[kLength]) {
+          tock = nextTickQueue[tickInfo[kIndex]++];
+          callback = tock.callback;
+          domain = tock.domain;
+          if (domain)
+            domain.enter();
+          threw = true;
+          try {
+            callback();
+            threw = false;
+          } finally {
+            if (threw)
+              tickDone();
+          }
+          if (1e4 < tickInfo[kIndex])
             tickDone();
+          if (domain)
+            domain.exit();
         }
-        if (1e4 < tickInfo[kIndex])
-          tickDone();
-        if (domain)
-          domain.exit();
-      }
+        tickDone();
+        _runMicrotasks();
+        emitPendingUnhandledRejections();
+      } while (tickInfo[kLength] !== 0);
+    }
 
-      tickDone();
+    function TickObject(c) {
+      this.callback = c;
+      this.domain = process.domain || null;
     }
 
     function nextTick(callback) {
       if (process._exiting)
         return;
 
-      var obj = {
-        callback: callback,
-        domain: process.domain || null
-      };
-
-      nextTickQueue.push(obj);
+      nextTickQueue.push(new TickObject(callback));
       tickInfo[kLength]++;
     }
 
index 357ac88..385724b 100644 (file)
@@ -8,5 +8,5 @@ setTimeout(function() {
   var ms = (hr[0] * 1e3) + (hr[1] / 1e6);
   var delta = ms - TIMEOUT;
   console.log('timer fired in', delta);
-  assert.ok(delta > 0, 'Timer fired early');
+  assert.ok(delta > -0.5, 'Timer fired early');
 }, TIMEOUT);