IndexedDB 2.0: Send operations off to the server in batches instead of one at a time.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Nov 2016 22:59:28 +0000 (22:59 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 30 Nov 2016 22:59:28 +0000 (22:59 +0000)
https://bugs.webkit.org/show_bug.cgi?id=165221

Reviewed by Myles C. Maxfield.

No new tests (No observable behavior change).

On a profile of "Lots of writes to an IndexedDB", timer scheduling/firing presented as over 10% of the time.

This patch negates much of that.

* Modules/indexeddb/IDBTransaction.cpp:
(WebCore::IDBTransaction::pendingOperationTimerFired): Send 100 operations off to the server
  before spinning the runloop, instead of only 1.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@209157 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/indexeddb/IDBTransaction.cpp

index ecaa22f..f373323 100644 (file)
@@ -1,3 +1,20 @@
+2016-11-30  Brady Eidson  <beidson@apple.com>
+
+        IndexedDB 2.0: Send operations off to the server in batches instead of one at a time.
+        https://bugs.webkit.org/show_bug.cgi?id=165221
+
+        Reviewed by Myles C. Maxfield.
+
+        No new tests (No observable behavior change).
+
+        On a profile of "Lots of writes to an IndexedDB", timer scheduling/firing presented as over 10% of the time.
+
+        This patch negates much of that.
+
+        * Modules/indexeddb/IDBTransaction.cpp:
+        (WebCore::IDBTransaction::pendingOperationTimerFired): Send 100 operations off to the server
+          before spinning the runloop, instead of only 1.
+
 2016-11-30  Antoine Quint  <graouts@apple.com>
 
         [Modern Media Controls] Controls are not visible when returning from picture-in-picture playback
index eb0d87b..4497347 100644 (file)
@@ -406,17 +406,19 @@ void IDBTransaction::pendingOperationTimerFired()
     if (!m_transactionOperationsInProgressQueue.isEmpty() && !m_transactionOperationsInProgressQueue.last()->nextRequestCanGoToServer())
         return;
 
-    if (!m_pendingTransactionOperationQueue.isEmpty()) {
+    // We want to batch operations together without spinning the runloop for performance,
+    // but don't want to affect responsiveness of the main thread.
+    // This number is a good compromise in ad-hoc testing.
+    static const size_t operationBatchLimit = 128;
+
+    for (size_t iterations = 0; !m_pendingTransactionOperationQueue.isEmpty() && iterations < operationBatchLimit; ++iterations) {
         auto operation = m_pendingTransactionOperationQueue.takeFirst();
         m_transactionOperationsInProgressQueue.append(operation.get());
         operation->perform();
 
-        // If this operation we just started has an associated IDBRequest, we might be able to send
-        // another operation to the server before it completes.
-        if (operation->idbRequest() && !m_pendingTransactionOperationQueue.isEmpty())
-            schedulePendingOperationTimer();
+        if (!operation->nextRequestCanGoToServer())
+            break;
 
-        return;
     }
 
     if (!m_transactionOperationMap.isEmpty() || !m_openRequests.isEmpty())