Blob Blame History Raw
From c733429f4fa9696fb027ddc946e54f6bbb68deaf Mon Sep 17 00:00:00 2001
From: Milian Wolff <mail@milianw.de>
Date: Wed, 10 Dec 2014 21:16:45 +0100
Subject: [PATCH 30/30] Preallocate a capacity of 16 for the returned list.

See also 159abaf2f372eaa633db8f69ff6b1edd459998cc in kdepimlibs on
why. I'll quote it here again:

    In my data, most often the final size of fetchResponse is 16.
    By reserving that data upfront, we can get rid of 3/4 of the
    list allocations, according to the growth-strategy outlined here:
    http://qt-project.org/doc/qt-4.8/containers.html#growth-strategies
    I.e. before, we'd allocate 4, 8, 12, 16. Now we directly allocate
    room for 16.

Thing is, doing this outside of akonadi has no effect, as QList::clear
destroys the internal buffer. With the added benchmark, I now verified
that this patch here does have a positive effect.
---
 libs/imapparser.cpp                |  2 ++
 libs/tests/imapparserbenchmark.cpp | 52 ++++++++++++++++++++++++++------------
 2 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/libs/imapparser.cpp b/libs/imapparser.cpp
index f3301e7..f5a7457 100644
--- a/libs/imapparser.cpp
+++ b/libs/imapparser.cpp
@@ -79,6 +79,8 @@ int parseParenthesizedListHelper( const QByteArray &data, T &result, int start )
     return start;
   }
 
+  result.reserve(16);
+
   int count = 0;
   int sublistBegin = start;
   bool insideQuote = false;
diff --git a/libs/tests/imapparserbenchmark.cpp b/libs/tests/imapparserbenchmark.cpp
index ee861a0..7545238 100644
--- a/libs/tests/imapparserbenchmark.cpp
+++ b/libs/tests/imapparserbenchmark.cpp
@@ -27,6 +27,25 @@ Q_DECLARE_METATYPE( QList<QByteArray> )
 class ImapParserBenchmark : public QObject
 {
   Q_OBJECT
+  private:
+    void geneateParseParenthesizedListData()
+    {
+      QTest::addColumn<QByteArray>( "data" );
+      QTest::newRow( "empty" ) << QByteArray();
+      QTest::newRow( "unnested" ) << QByteArray("(\"Foo Bar\" NIL \"foobar\" \"test.com\")");
+      QTest::newRow( "nested" ) << QByteArray("((\"Foo Bar\" NIL \"foobar\" \"test.com\"))");
+      QTest::newRow( "nested-long" ) << QByteArray("(UID 86 REV 0 MIMETYPE \"message/rfc822\" COLLECTIONID 13 SIZE 6114 FLAGS (\\SEEN)"
+                                                   " ANCESTORS ((13 \"/INBOX\") (12 \"imap://mail@mail.test.com/\") (0 \"\")) PLD:ENVELOPE[1] {396}"
+                                                   " (\"Fri, 04 Jun 2010 09:07:54 +0200\" \"Re: [ADMIN] foobar available again!\""
+                                                   " ((\"Foo Bar\" NIL \"foobar\" \"test.com\"))"
+                                                   " NIL NIL"
+                                                   " ((\"Asdf Bla Blub\" NIL \"asdf.bla.blub\" \"123test.org\"))"
+                                                   " ((NIL NIL \"muh.kuh\" \"lalala.com\") (\"Konqi KDE\" NIL \"konqi\" \"kde.org\") (NIL NIL \"all\" \"test.com\"))"
+                                                   " NIL \"<201006040905.33367.foo.bar@test.com>\" \"<4C08A64A.9020205@123test.org>\""
+                                                   " \"<201006040142.56540.muh.kuh@lalala.com> <201006040704.39648.konqi@kde.org> <201006040905.33367.foo.bar@test.com>\""
+                                                   "))");
+    }
+
   private Q_SLOTS:
     void quote_data()
     {
@@ -68,25 +87,12 @@ class ImapParserBenchmark : public QObject
       }
     }
 
-    void parseParenthesizedList_data()
+    void parseParenthesizedQVarLengthArray_data()
     {
-      QTest::addColumn<QByteArray>( "data" );
-      QTest::newRow( "empty" ) << QByteArray();
-      QTest::newRow( "unnested" ) << QByteArray("(\"Foo Bar\" NIL \"foobar\" \"test.com\")");
-      QTest::newRow( "nested" ) << QByteArray("((\"Foo Bar\" NIL \"foobar\" \"test.com\"))");
-      QTest::newRow( "nested-long" ) << QByteArray("(UID 86 REV 0 MIMETYPE \"message/rfc822\" COLLECTIONID 13 SIZE 6114 FLAGS (\\SEEN)"
-                                                   " ANCESTORS ((13 \"/INBOX\") (12 \"imap://mail@mail.test.com/\") (0 \"\")) PLD:ENVELOPE[1] {396}"
-                                                   " (\"Fri, 04 Jun 2010 09:07:54 +0200\" \"Re: [ADMIN] foobar available again!\""
-                                                   " ((\"Foo Bar\" NIL \"foobar\" \"test.com\"))"
-                                                   " NIL NIL"
-                                                   " ((\"Asdf Bla Blub\" NIL \"asdf.bla.blub\" \"123test.org\"))"
-                                                   " ((NIL NIL \"muh.kuh\" \"lalala.com\") (\"Konqi KDE\" NIL \"konqi\" \"kde.org\") (NIL NIL \"all\" \"test.com\"))"
-                                                   " NIL \"<201006040905.33367.foo.bar@test.com>\" \"<4C08A64A.9020205@123test.org>\""
-                                                   " \"<201006040142.56540.muh.kuh@lalala.com> <201006040704.39648.konqi@kde.org> <201006040905.33367.foo.bar@test.com>\""
-                                                   "))");
+      geneateParseParenthesizedListData();
     }
 
-    void parseParenthesizedList()
+    void parseParenthesizedQVarLengthArray()
     {
       QFETCH( QByteArray, data );
       QVarLengthArray<QByteArray, 16> result;
@@ -95,6 +101,20 @@ class ImapParserBenchmark : public QObject
       }
     }
 
+    void parseParenthesizedQList_data()
+    {
+      geneateParseParenthesizedListData();
+    }
+
+    void parseParenthesizedQList()
+    {
+      QFETCH( QByteArray, data );
+      QList<QByteArray> result;
+      QBENCHMARK {
+        ImapParser::parseParenthesizedList( data, result, 0 );
+      }
+    }
+
     void parseString_data()
     {
       QTest::addColumn<QByteArray>( "data" );
-- 
2.1.0