-
Notifications
You must be signed in to change notification settings - Fork 27.4k
perf($rootScope): make postDigestQueue more efficient #14545
Conversation
9524d49
to
06d3fac
Compare
This looks pretty good to me. I think they tiny extra bytes are totally worth it if we can get a speed boost on every OOC, have you done any benchmarks ? |
There is a benchmark on the page from where I took the implementation of queue. |
Since for (var i=0, len=postDigestQueue.length; i<len; i++) {
try {
postDigestQueue[i]();
} catch (e) {
$exceptionHandler(e);
}
}
postDigestQueue.length = 0; That seems simpler and does only one |
Because this loop can be called recursively inside |
Ah, no wonder that simple solution was never used ^_^ |
This change looks interesting, but the code at http://code.stephenmorley.org/javascript/queues/ is not MIT licensed, so it cannot be merged into Angular. |
On the other hand, it's quite difficult to implement queue in such a way that it wouldn't resemble and look like a work derived from this CC0 licensed code. |
b31d605
to
0f25be0
Compare
@lgalfaso I rewrote it a bit. Please have a look. Now |
Similar to what @jbedard proposed, couldn't we just empty the queue when it's empty ? Not a big deal, but it could save a few |
I would be interested in benchmarking this against a linked list queue. |
@petebacondarwin Linked list seems to be a bit slower than that queue. You can get the script I used for benchmarking from here. |
0f25be0
to
d8eec2e
Compare
@gkalpak Although my benchmark script doesn't show any improvement from doing this, I moved the Also I used this queue implementation for |
d8eec2e
to
c5fa76b
Compare
As a play on what @jbedard suggested, what if you looped through the // At the top of the `$RootScopeProvider` closure
var postDigestQueuePosition = 0;
while(postDigestQueuePosition < postDigestQueue.length) {
try {
postDigestQueue[postDigestQueuePosition++]();
} catch (e) {
$exceptionHandler(e);
}
}
postDigestQueue.length = postDigestQueuePosition = 0; How does that compare perf wise to the queue? It's also a more minimalistic change |
c5fa76b
to
af7db57
Compare
@dcherman You're right. What you wrote makes perfect sense. I've updated the commit. Of course, it's better than the queue as it doesn't involve any calls to methods like |
Nice 👍 |
This looks pretty good now. Thanks @thorn0 |
@@ -848,13 +849,14 @@ function $RootScopeProvider() { | |||
|
|||
clearPhase(); | |||
|
|||
while (postDigestQueue.length) { | |||
while (postDigestQueuePosition < postDigestQueue.length) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not keep postDigestQueuePosition
local and use a for loop as with asyncQueue
above ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above. This loop can be reentered recursively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. Which makes me wonder: Could the same happen with the asyncQueue
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - the asyncQueue
is drained during the $digest
cycle where postDigestQueue
is drained outside of it. As a result, you can't recurse into it since you'd have gotten a digest in progress error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added these explanations as comments in the code.
af7db57
to
d0dd06a
Compare
d0dd06a
to
df5864e
Compare
By using a pointer to the current start of the queue and only clearing up the queue storage later, we save lots of time that was spent manipulating arrays with `slice` Closes #14545
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Performance improvement
What is the current behavior? (You can also link to an open issue here)
#14534
What is the new behavior (if this is a feature change)?
Using this implementation of queue instead of an array.
Does this PR introduce a breaking change?
postDigestQueue
is available as$rootScope.$$postDigestQueue
. So it can be considered a breaking change.Please check if the PR fulfills these requirements