From eb47988f3f58c9f35e03b686eb332e027ff193eb Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Mon, 25 May 2009 12:20:47 +0200
Subject: [PATCH] qstringbuilder: handle QLatin1Strings directly.

This also extends and re-organizes the benchmark a bit
---
 src/libs/utils/qstringbuilder.h               |  25 +-
 tests/benchmarks/qstringbuilder/main.cpp      | 277 +++++++++++-------
 .../qstringbuilder/qstringbuilder.pro         |   3 +
 3 files changed, 195 insertions(+), 110 deletions(-)

diff --git a/src/libs/utils/qstringbuilder.h b/src/libs/utils/qstringbuilder.h
index c32f2dae3f3..30a5a53e3a2 100644
--- a/src/libs/utils/qstringbuilder.h
+++ b/src/libs/utils/qstringbuilder.h
@@ -59,11 +59,11 @@ public:
     inline int size() const { return m_size; }
     inline const char *data() const { return m_data; }
 
-    void append(QChar *&out) const
+    void appendTo(QChar *&out) const
     {
         const char *s = m_data;
         for (int i = m_size; --i >= 0;)    
-            *out++ = *s++;
+            *out++ = QLatin1Char(*s++);
     }
 
     operator QString() const
@@ -75,7 +75,7 @@ public:
         s.resize(m_size);
 #endif
         QChar *d = s.data();
-        append(d);
+        appendTo(d);
         return s;
     }
 
@@ -100,7 +100,7 @@ public:
         s.resize(this->size());
 #endif
         QChar *d = s.data();
-        this->append(d);
+        this->appendTo(d);
         return s;
     }
 
@@ -114,7 +114,7 @@ public:
 
     inline int size() const { return a->size(); }
 
-    inline void append(QChar *&out) const
+    inline void appendTo(QChar *&out) const
     {
         const int n = a->size();
         memcpy(out, (char*)a->constData(), sizeof(QChar) * n);
@@ -133,12 +133,23 @@ int qStringBuilderSize(const A a) { return a.size(); }
 
 inline int qStringBuilderSize(const char) { return 1; }
 
+inline int qStringBuilderSize(const QLatin1Char) { return 1; }
+
+inline int qStringBuilderSize(const QLatin1String a) { return qstrlen(a.latin1()); }
 
 template <typename A>
-inline void qStringBuilderAppend(const A a, QChar *&out) { a.append(out); }
+inline void qStringBuilderAppend(const A a, QChar *&out) { a.appendTo(out); }
 
 inline void qStringBuilderAppend(char c, QChar *&out) { *out++ = QLatin1Char(c); }
 
+inline void qStringBuilderAppend(QLatin1Char c, QChar *&out) { *out++ = c; }
+
+inline void qStringBuilderAppend(QLatin1String a, QChar *&out)
+{
+    for (const char *s = a.latin1(); *s; )
+        *out++ = QLatin1Char(*s++);
+}
+
 
 template <typename A, typename B>
 class QStringBuilderPair
@@ -151,7 +162,7 @@ public:
         return qStringBuilderSize(a) + qStringBuilderSize(b);
     }
 
-    inline void append(QChar *&out) const
+    inline void appendTo(QChar *&out) const
     {
         qStringBuilderAppend(a, out);
         qStringBuilderAppend(b, out);
diff --git a/tests/benchmarks/qstringbuilder/main.cpp b/tests/benchmarks/qstringbuilder/main.cpp
index 0967e1682e4..c4a832c7049 100644
--- a/tests/benchmarks/qstringbuilder/main.cpp
+++ b/tests/benchmarks/qstringbuilder/main.cpp
@@ -10,140 +10,211 @@
 #define COMPARE(a, b) QCOMPARE(a, b)
 //#define COMPARE(a, b)
 
-#define SEP(s) qDebug() << "\n------- " s "  ----------";
+#define SEP(s) qDebug() << "\n\n-------- " s "  ---------";
+#define L(s) QLatin1String(s)
 
 class tst_qstringbuilder : public QObject
 {
     Q_OBJECT
 
 public:
-    tst_qstringbuilder();
+    tst_qstringbuilder()
+      : l1literal("some string literal"),
+        l1string("some string literal"),
+        string(l1string),
+        achar('c')
+    {}
+
+
+public:
+    enum { N = 10000 };
+
+    int run_traditional()
+    {
+        int s = 0;
+        for (int i = 0; i < N; ++i) {
+#if 0
+            s += QString(l1string + l1string).size();
+            s += QString(l1string + l1string + l1string).size();
+            s += QString(l1string + l1string + l1string + l1string).size();
+            s += QString(l1string + l1string + l1string + l1string + l1string).size();
+#endif
+            s += QString(achar + l1string + achar).size();
+        }
+        return s;
+    }
+
+    int run_builder()
+    {
+        int s = 0;
+        for (int i = 0; i < N; ++i) {
+#if 0
+            s += QString(l1literal % l1literal).size();
+            s += QString(l1literal % l1literal % l1literal).size();
+            s += QString(l1literal % l1literal % l1literal % l1literal).size();
+            s += QString(l1literal % l1literal % l1literal % l1literal % l1literal).size();
+#endif
+            s += QString(achar % l1literal % achar).size();
+        }
+        return s;
+    }
 
 private slots:
-    void separator_2() { SEP("string + string  (builder first)"); }
-    void b_2_l1literal();
-    void s_2_l1string();
 
-    void separator_3() { SEP("3 strings"); }
-    void b_3_l1literal();
-    void s_3_l1string();
+    void separator_0() {
+        qDebug() << "\nIn each block the QStringBuilder based result appear first, "
+            "QStringBased second.\n";
+    }
 
-    void separator_4() { SEP("4 strings"); }
-    void b_4_l1literal();
-    void s_4_l1string();
+    void separator_1() { SEP("literal + literal  (builder first)"); }
 
-    void separator_5() { SEP("5 strings"); }
-    void b_5_l1literal();
-    void s_5_l1string();
+    void b_2_l1literal() {
+        QBENCHMARK { r = l1literal % l1literal; }
+        COMPARE(r, l1string + l1string);
+    }
+    void s_2_l1string() {
+        QBENCHMARK { r = l1string + l1string; }
+        COMPARE(r, QString(l1literal % l1literal));
+    }
 
-    void separator_6() { SEP("4 chars"); }
-    void b_string_4_char();
-    void s_string_4_char();
 
-    void separator_7() { SEP("char + string + char"); }
-    void b_char_string_char();
-    void s_char_string_char();
+    void separator_2() { SEP("2 strings"); }
 
-private:
-    const QLatin1Literal l1literal;
-    const QLatin1String l1string;
-    const QString string;
-    const char achar;
-};
+    void b_2_string() {
+        QBENCHMARK { r = string % string; }
+        COMPARE(r, string + string);
+    }
+    void s_2_string() {
+        QBENCHMARK { r = string + string; }
+        COMPARE(r, QString(string % string));
+    }
 
 
-tst_qstringbuilder::tst_qstringbuilder()
-  : l1literal("some literal"),
-    l1string("some literal"),
-    string(l1string),
-    achar('c')
-{}
+    void separator_2b() { SEP("3 strings"); }
 
-void tst_qstringbuilder::b_2_l1literal()
-{
-    QString result;
-    QBENCHMARK { result = l1literal % l1literal; }
-    COMPARE(result, l1string + l1string);
-}
+    void b_3_string() {
+        QBENCHMARK { r = string % string % string; }
+        COMPARE(r, string + string + string);
+    }
+    void s_3_string() {
+        QBENCHMARK { r = string + string + string; }
+        COMPARE(r, QString(string % string % string));
+    }
 
-void tst_qstringbuilder::b_3_l1literal()
-{
-    QString result;
-    QBENCHMARK { result = l1literal % l1literal % l1literal; }
-    COMPARE(result, l1string + l1string + l1string);
-}
 
-void tst_qstringbuilder::b_4_l1literal()
-{
-    QString result;
-    QBENCHMARK { result = l1literal % l1literal % l1literal % l1literal; }
-    COMPARE(result, l1string + l1string + l1string + l1string);
-}
+    void separator_2a() { SEP("string + literal  (builder first)"); }
 
-void tst_qstringbuilder::b_5_l1literal()
-{
-    QString result;
-    QBENCHMARK { result = l1literal % l1literal % l1literal % l1literal %l1literal; }
-    COMPARE(result, l1string + l1string + l1string + l1string + l1string);
-}
+    void b_string_l1literal() {
+        QBENCHMARK { r = string % l1literal; }
+        COMPARE(r, string + l1string);
+    }
+    void b_string_l1string() {
+        QBENCHMARK { r = string % l1string; }
+        COMPARE(r, string + l1literal);
+    }
+    void s_string_l1literal() {
+        QBENCHMARK { r = string + l1literal; }
+        COMPARE(r, QString(string % l1string));
+    }
+    void s_string_l1string() {
+        QBENCHMARK { r = string + l1string; }
+        COMPARE(r, QString(string % l1literal));
+    }
 
-void tst_qstringbuilder::b_string_4_char()
-{
-    QString result;
-    QBENCHMARK { result = string + achar + achar + achar + achar; }
-    COMPARE(result, QString(string % achar % achar % achar % achar));
-}
 
-void tst_qstringbuilder::b_char_string_char()
-{
-    QString result;
-    QBENCHMARK { result = achar + string + achar; }
-    COMPARE(result, QString(achar % string % achar));
-}
+    void separator_3() { SEP("3 literals"); }
 
+    void b_3_l1literal() {
+        QBENCHMARK { r = l1literal % l1literal % l1literal; }
+        COMPARE(r, l1string + l1string + l1string);
+    }
+    void s_3_l1string() {
+        QBENCHMARK { r = l1string + l1string + l1string; }
+        COMPARE(r, QString(l1literal % l1literal % l1literal));
+    }
 
-void tst_qstringbuilder::s_2_l1string()
-{
-    QString result;
-    QBENCHMARK { result = l1string + l1string; }
-    COMPARE(result, QString(l1literal % l1literal));
-}
 
-void tst_qstringbuilder::s_3_l1string()
-{
-    QString result;
-    QBENCHMARK { result = l1string + l1string + l1string; }
-    COMPARE(result, QString(l1literal % l1literal % l1literal));
-}
+    void separator_4() { SEP("4 literals"); }
 
-void tst_qstringbuilder::s_4_l1string()
-{
-    QString result;
-    QBENCHMARK { result = l1string + l1string + l1string + l1string; }
-    COMPARE(result, QString(l1literal % l1literal % l1literal % l1literal));
-}
+    void b_4_l1literal() {
+        QBENCHMARK { r = l1literal % l1literal % l1literal % l1literal; }
+        COMPARE(r, l1string + l1string + l1string + l1string);
+    }
+    void s_4_l1string() {
+        QBENCHMARK { r = l1string + l1string + l1string + l1string; }
+        COMPARE(r, QString(l1literal % l1literal % l1literal % l1literal));
+    }
 
-void tst_qstringbuilder::s_5_l1string()
-{
-    QString result;
-    QBENCHMARK { result = l1string + l1string + l1string + l1string + l1string; }
-    COMPARE(result, QString(l1literal % l1literal % l1literal % l1literal % l1literal));
-}
 
-void tst_qstringbuilder::s_string_4_char()
-{
-    QString result;
-    QBENCHMARK { result = string + achar + achar + achar + achar; }
-    COMPARE(result, QString(string % achar % achar % achar % achar));
-}
+    void separator_5() { SEP("5 literals"); }
+
+    void b_5_l1literal() {
+        QBENCHMARK { r = l1literal % l1literal % l1literal % l1literal %l1literal; }
+        COMPARE(r, l1string + l1string + l1string + l1string + l1string);
+    }
+
+    void s_5_l1string() {
+        QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; }
+        COMPARE(r, QString(l1literal % l1literal % l1literal % l1literal % l1literal));
+    }
+
+
+    void separator_6() { SEP("4 chars"); }
+
+    void b_string_4_char() {
+        QBENCHMARK { r = string + achar + achar + achar + achar; }
+        COMPARE(r, QString(string % achar % achar % achar % achar));
+    }
+
+    void s_string_4_char() {
+        QBENCHMARK { r = string + achar + achar + achar + achar; }
+        COMPARE(r, QString(string % achar % achar % achar % achar));
+    }
+
+
+    void separator_7() { SEP("char + string + char"); }
+
+    void b_char_string_char() {
+        QBENCHMARK { r = achar + string + achar; }
+        COMPARE(r, QString(achar % string % achar));
+    }
+
+    void s_char_string_char() {
+        QBENCHMARK { r = achar + string + achar; }
+        COMPARE(r, QString(achar % string % achar));
+    }
+
+private:
+    const QLatin1Literal l1literal;
+    const QLatin1String l1string;
+    const QString string;
+    const QLatin1Char achar;
+
+    QString r;
+};
+
 
-void tst_qstringbuilder::s_char_string_char()
+int main(int argc, char *argv[])
 {
-    QString result;
-    QBENCHMARK { result = achar + string + achar; }
-    COMPARE(result, QString(achar % string % achar));
+    if (argc == 2 && (argv[1] == L("--run-builder") || argv[1] == L("-b"))) {
+        tst_qstringbuilder test;
+        return test.run_builder();
+    }
+
+    if (argc == 2 && (argv[1] == L("--run-traditional") || argv[1] == L("-t"))) {
+        tst_qstringbuilder test;
+        return test.run_traditional();
+    }
+
+    if (argc == 1) {
+        QCoreApplication app(argc, argv);
+        QStringList args = app.arguments();
+        tst_qstringbuilder test;
+        return QTest::qExec(&test, argc, argv);
+    }
+
+    qDebug() << "Usage: " << argv[0] << " [--run-builder|-r|--run-traditional|-t]";
 }
 
-QTEST_MAIN(tst_qstringbuilder)
 
 #include "main.moc"
diff --git a/tests/benchmarks/qstringbuilder/qstringbuilder.pro b/tests/benchmarks/qstringbuilder/qstringbuilder.pro
index 578ca1d3ac7..870f2e26bba 100644
--- a/tests/benchmarks/qstringbuilder/qstringbuilder.pro
+++ b/tests/benchmarks/qstringbuilder/qstringbuilder.pro
@@ -4,6 +4,9 @@ TARGET = tst_qstringbuilder
 STRINGBUILDERDIR = ../../../src/libs/utils
 INCLUDEPATH += $$STRINGBUILDERDIR
 
+QMAKE_CXXFLAGS += -g
+QMAKE_CFLAGS += -g
+
 QT -= gui
 
 CONFIG += release
-- 
GitLab