@samitouri / QOS-React / commits / babace0c05

Add fast path for appending updates to the end of the queue

This is the most common case, so we should avoid scanning the entire list to get to the end.

Andrew Clark committed Dec 13, 2016 at 10:55 UTC babace0c059965b01767797adace4e765a4650d7
1 file changed +31 -22
src/renderers/shared/fiber/ReactFiberUpdateQueue.js
+31 -22
@@ -176,26 +176,41 @@ function insertUpdate(fiber : Fiber, update : Update) : void {
176
177 const priorityLevel = update.priorityLevel;
178
179 - // TODO: Fast path where last item in the queue has greater or equal priority.
180 -
181 - let insertAfter1 = null;
182 - let insertBefore1 = queue1.first;
183 - while (insertBefore1 && comparePriority(insertBefore1.priorityLevel, priorityLevel) <= 0) {
184 - insertAfter1 = insertBefore1;
185 - insertBefore1 = insertBefore1.next;
179 + let queue = queue1;
180 + let insertAfter1;
181 + let insertBefore1;
182 + let insertAfter2;
183 + let insertBefore2;
184 + for (let i = 0; queue && i < 2; i++) {
185 + let insertAfter = null;
186 + let insertBefore = null;
187 + if (queue.last && comparePriority(queue.last.priorityLevel, priorityLevel) <= 0) {
188 + // Fast path for the common case where the update should be inserted at
189 + // the end of the queue.
190 + insertAfter = queue.last;
191 + } else {
192 + insertBefore = queue.first;
193 + while (insertBefore && comparePriority(insertBefore.priorityLevel, priorityLevel) <= 0) {
194 + insertAfter = insertBefore;
195 + insertBefore = insertBefore.next;
196 + }
197 + }
198 + if (i === 0) {
199 + insertAfter1 = insertAfter;
200 + insertBefore1 = insertBefore;
201 + queue = queue2;
202 + } else {
203 + insertAfter2 = insertAfter;
204 + insertBefore2 = insertBefore;
205 + queue = null;
206 + }
207 }
208 +
209 const update1 = update;
210 + insertUpdateIntoQueue(queue1, update1, insertAfter1, insertBefore1);
211
189 - let insertAfter2 = null;
190 - let insertBefore2 = null;
191 - let update2 = null;
212 if (queue2) {
193 - insertBefore2 = queue2.first;
194 - while (insertBefore2 && comparePriority(insertBefore2.priorityLevel, priorityLevel) <= 0) {
195 - insertAfter2 = insertBefore2;
196 - insertBefore2 = insertBefore2.next;
197 - }
198 -
213 + let update2;
214 if (insertBefore1 === insertBefore2) {
215 // The update is inserted into the same position of both lists. There's no
216 // need to clone the update.
@@ -206,11 +221,6 @@ function insertUpdate(fiber : Fiber, update : Update) : void {
221 // time we commit.
222 update2 = cloneUpdate(update1);
223 }
209 - }
210 -
211 - // Now we're ready to insert the updates into their queues.
212 - insertUpdateIntoQueue(queue1, update1, insertAfter1, insertBefore1);
213 - if (queue2 && update2) {
224 insertUpdateIntoQueue(queue2, update2, insertAfter2, insertBefore2);
225 }
226 }
@@ -296,7 +306,6 @@ exports.addForceUpdate = addForceUpdate;
306
307
308 function addCallback(fiber : Fiber, callback: Callback, priorityLevel : PriorityLevel) : void {
299 - // TODO: Fast path where last item in queue has equal priority.
309 const update : Update = {
310 priorityLevel,
311 partialState: null,