summaryrefslogtreecommitdiffstats
path: root/tests/benchmarks/corelib/text
diff options
context:
space:
mode:
Diffstat (limited to 'tests/benchmarks/corelib/text')
-rw-r--r--tests/benchmarks/corelib/text/qbytearray/main.cpp264
-rw-r--r--tests/benchmarks/corelib/text/qbytearray/qbytearray.pro7
-rw-r--r--tests/benchmarks/corelib/text/qchar/main.cpp136
-rw-r--r--tests/benchmarks/corelib/text/qchar/qchar.pro3
-rw-r--r--tests/benchmarks/corelib/text/qlocale/main.cpp70
-rw-r--r--tests/benchmarks/corelib/text/qlocale/qlocale.pro4
-rw-r--r--tests/benchmarks/corelib/text/qregexp/main.cpp615
-rw-r--r--tests/benchmarks/corelib/text/qregexp/qregexp.pro20
-rw-r--r--tests/benchmarks/corelib/text/qregexp/qregexp.qrc6
-rw-r--r--tests/benchmarks/corelib/text/qstring/main.cpp193
-rw-r--r--tests/benchmarks/corelib/text/qstring/qstring.pro5
-rw-r--r--tests/benchmarks/corelib/text/qstringbuilder/main.cpp420
-rw-r--r--tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro11
-rw-r--r--tests/benchmarks/corelib/text/qstringlist/.gitignore1
-rw-r--r--tests/benchmarks/corelib/text/qstringlist/main.cpp201
-rw-r--r--tests/benchmarks/corelib/text/qstringlist/qstringlist.pro5
-rw-r--r--tests/benchmarks/corelib/text/text.pro9
17 files changed, 1970 insertions, 0 deletions
diff --git a/tests/benchmarks/corelib/text/qbytearray/main.cpp b/tests/benchmarks/corelib/text/qbytearray/main.cpp
new file mode 100644
index 0000000000..e421e7436b
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qbytearray/main.cpp
@@ -0,0 +1,264 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QDebug>
+#include <QIODevice>
+#include <QFile>
+#include <QString>
+
+#include <qtest.h>
+
+
+class tst_qbytearray : public QObject
+{
+ Q_OBJECT
+ QByteArray sourcecode;
+private slots:
+ void initTestCase();
+ void append();
+ void append_data();
+
+ void latin1Uppercasing_qt54();
+ void latin1Uppercasing_xlate();
+ void latin1Uppercasing_xlate_checked();
+ void latin1Uppercasing_category();
+ void latin1Uppercasing_bitcheck();
+};
+
+void tst_qbytearray::initTestCase()
+{
+ QFile self(QFINDTESTDATA("main.cpp"));
+ QVERIFY(self.open(QIODevice::ReadOnly));
+ sourcecode = self.readAll();
+}
+
+void tst_qbytearray::append_data()
+{
+ QTest::addColumn<int>("size");
+ QTest::newRow("1") << int(1);
+ QTest::newRow("10") << int(10);
+ QTest::newRow("100") << int(100);
+ QTest::newRow("1000") << int(1000);
+ QTest::newRow("10000") << int(10000);
+ QTest::newRow("100000") << int(100000);
+ QTest::newRow("1000000") << int(1000000);
+ QTest::newRow("10000000") << int(10000000);
+ QTest::newRow("100000000") << int(100000000);
+}
+
+void tst_qbytearray::append()
+{
+ QFETCH(int, size);
+
+ QByteArray ba;
+ QBENCHMARK {
+ QByteArray ba2(size, 'x');
+ ba.append(ba2);
+ ba.clear();
+ }
+}
+
+void tst_qbytearray::latin1Uppercasing_qt54()
+{
+ QByteArray s = sourcecode;
+ s.detach();
+
+ // the following was copied from qbytearray.cpp (except for the QBENCHMARK macro):
+ uchar *p_orig = reinterpret_cast<uchar *>(s.data());
+ uchar *e = reinterpret_cast<uchar *>(s.end());
+
+ QBENCHMARK {
+ uchar *p = p_orig;
+ if (p) {
+ while (p != e) {
+ *p = QChar::toLower((ushort)*p);
+ p++;
+ }
+ }
+ }
+}
+
+
+/*
+#!/usr/bin/perl -l
+use feature "unicode_strings"
+for (0..255) {
+ $up = uc(chr($_));
+ $up = chr($_) if ord($up) > 0x100 || length $up > 1;
+ printf "0x%02x,", ord($up);
+ print "" if ($_ & 0xf) == 0xf;
+}
+*/
+static const uchar uppercased[256] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x7b,0x7c,0x7d,0x7e,0x7f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+ 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+ 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+ 0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xf7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xff
+};
+void tst_qbytearray::latin1Uppercasing_xlate()
+{
+ QByteArray output = sourcecode;
+ output.detach();
+ char *dst_orig = output.data();
+ const char *src_orig = sourcecode.constBegin();
+ const char *end = sourcecode.constEnd();
+ QBENCHMARK {
+ char *dst = dst_orig;
+ for (const char *src = src_orig; src != end; ++src, ++dst)
+ *dst = uppercased[uchar(*src)];
+ }
+}
+
+void tst_qbytearray::latin1Uppercasing_xlate_checked()
+{
+ QByteArray output = sourcecode;
+ output.detach();
+ char *dst_orig = output.data();
+ const char *src_orig = sourcecode.constBegin();
+ const char *end = sourcecode.constEnd();
+ QBENCHMARK {
+ char *dst = dst_orig;
+ for (const char *src = src_orig; src != end; ++src, ++dst) {
+ uchar ch = uchar(*src);
+ uchar converted = uppercased[ch];
+ if (ch != converted)
+ *dst = converted;
+ }
+ }
+}
+
+/*
+#!/bin/perl -l
+use feature "unicode_strings";
+sub categorize($) {
+ # 'ß' and 'ÿ' are lowercase, but we cannot uppercase them
+ return 0 if $_[0] == 0xDF || $_[0] == 0xFF;
+ $ch = chr($_[0]);
+ return 2 if uc($ch) ne $ch;
+ return 1 if lc($ch) ne $ch;
+ return 0;
+}
+for (0..255) {
+ printf "%d,", categorize($_);
+ print "" if ($_ & 0xf) == 0xf;
+}
+*/
+static const char categories[256] = {
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0
+};
+
+void tst_qbytearray::latin1Uppercasing_category()
+{
+ QByteArray output = sourcecode;
+ output.detach();
+ char *dst_orig = output.data();
+ const char *src_orig = sourcecode.constBegin();
+ const char *end = sourcecode.constEnd();
+ QBENCHMARK {
+ char *dst = dst_orig;
+ for (const char *src = src_orig; src != end; ++src, ++dst)
+ *dst = categories[uchar(*src)] == 1 ? *src & ~0x20 : *src;
+ }
+}
+
+/*
+#!/bin/perl -l
+use feature "unicode_strings";
+sub categorize($) {
+ # 'ß' and 'ÿ' are lowercase, but we cannot uppercase them
+ return 0 if $_[0] == 0xDF || $_[0] == 0xFF;
+ $ch = chr($_[0]);
+ return 2 if uc($ch) ne $ch;
+ return 1 if lc($ch) ne $ch;
+ return 0;
+}
+for $row (0..7) {
+ $val = 0;
+ for $col (0..31) {
+ $val |= (1<<$col)
+ if categorize($row * 31 + $col) == 2;
+ }
+ printf "0x%08x,", $val;
+}
+*/
+
+static const quint32 shouldUppercase[8] = {
+ 0x00000000,0x00000000,0x00000000,0x3ffffff0,0x00000000,0x04000000,0x00000000,0xbfffff80
+};
+
+static bool bittest(const quint32 *data, uchar bit)
+{
+ static const unsigned bitsperelem = sizeof(*data) * CHAR_BIT;
+ return data[bit / bitsperelem] & (1 << (bit & (bitsperelem - 1)));
+}
+
+void tst_qbytearray::latin1Uppercasing_bitcheck()
+{
+ QByteArray output = sourcecode;
+ output.detach();
+ char *dst_orig = output.data();
+ const char *src_orig = sourcecode.constBegin();
+ const char *end = sourcecode.constEnd();
+ QBENCHMARK {
+ char *dst = dst_orig;
+ for (const char *src = src_orig; src != end; ++src, ++dst)
+ *dst = bittest(shouldUppercase, *src) ? uchar(*src) & ~0x20 : uchar(*src);
+ }
+}
+
+
+QTEST_MAIN(tst_qbytearray)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qbytearray/qbytearray.pro b/tests/benchmarks/corelib/text/qbytearray/qbytearray.pro
new file mode 100644
index 0000000000..cf28b0247f
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qbytearray/qbytearray.pro
@@ -0,0 +1,7 @@
+TEMPLATE = app
+TARGET = tst_bench_qbytearray
+
+QT = core testlib
+
+TESTDATA += main.cpp
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/text/qchar/main.cpp b/tests/benchmarks/corelib/text/qchar/main.cpp
new file mode 100644
index 0000000000..4dcf86786d
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qchar/main.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtTest/QtTest>
+#include <QChar>
+
+class tst_QChar: public QObject
+{
+ Q_OBJECT
+private slots:
+ void isUpper_data();
+ void isUpper();
+ void isLower_data();
+ void isLower();
+ void isLetter_data();
+ void isLetter();
+ void isDigit_data();
+ void isDigit();
+ void isLetterOrNumber_data();
+ void isLetterOrNumber();
+ void isSpace_data();
+ void isSpace();
+};
+
+void tst_QChar::isUpper_data()
+{
+ QTest::addColumn<QChar>("c");
+
+ QTest::newRow("k") << QChar('k');
+ QTest::newRow("K") << QChar('K');
+ QTest::newRow("5") << QChar('5');
+ QTest::newRow("\\0") << QChar();
+ QTest::newRow("space") << QChar(' ');
+ QTest::newRow("\\u3C20") << QChar(0x3C20);
+}
+
+void tst_QChar::isUpper()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isUpper();
+ }
+}
+
+void tst_QChar::isLower_data()
+{
+ isUpper_data();
+}
+
+void tst_QChar::isLower()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isLower();
+ }
+}
+
+void tst_QChar::isLetter_data()
+{
+ isUpper_data();
+}
+
+void tst_QChar::isLetter()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isLetter();
+ }
+}
+
+void tst_QChar::isDigit_data()
+{
+ isUpper_data();
+}
+
+void tst_QChar::isDigit()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isDigit();
+ }
+}
+
+void tst_QChar::isLetterOrNumber_data()
+{
+ isUpper_data();
+}
+
+void tst_QChar::isLetterOrNumber()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isLetterOrNumber();
+ }
+}
+
+void tst_QChar::isSpace_data()
+{
+ isUpper_data();
+}
+
+void tst_QChar::isSpace()
+{
+ QFETCH(QChar, c);
+ QBENCHMARK {
+ c.isSpace();
+ }
+}
+
+QTEST_MAIN(tst_QChar)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qchar/qchar.pro b/tests/benchmarks/corelib/text/qchar/qchar.pro
new file mode 100644
index 0000000000..80a9861f48
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qchar/qchar.pro
@@ -0,0 +1,3 @@
+TARGET = tst_bench_qchar
+QT = core testlib
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/text/qlocale/main.cpp b/tests/benchmarks/corelib/text/qlocale/main.cpp
new file mode 100644
index 0000000000..38d94af143
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qlocale/main.cpp
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QLocale>
+#include <QTest>
+
+class tst_QLocale : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void toUpper_QLocale_1();
+ void toUpper_QLocale_2();
+ void toUpper_QString();
+};
+
+static QString data()
+{
+ return QStringLiteral("/qt-5/qtbase/tests/benchmarks/corelib/tools/qlocale");
+}
+
+#define LOOP(s) for (int i = 0; i < 5000; ++i) { s; }
+
+void tst_QLocale::toUpper_QLocale_1()
+{
+ QString s = data();
+ QBENCHMARK { LOOP(QLocale().toUpper(s)) }
+}
+
+void tst_QLocale::toUpper_QLocale_2()
+{
+ QString s = data();
+ QLocale l;
+ QBENCHMARK { LOOP(l.toUpper(s)) }
+}
+
+void tst_QLocale::toUpper_QString()
+{
+ QString s = data();
+ QBENCHMARK { LOOP(s.toUpper()) }
+}
+
+QTEST_MAIN(tst_QLocale)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qlocale/qlocale.pro b/tests/benchmarks/corelib/text/qlocale/qlocale.pro
new file mode 100644
index 0000000000..e56bbe0341
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qlocale/qlocale.pro
@@ -0,0 +1,4 @@
+TARGET = tst_bench_qlocale
+QT = core testlib
+
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/text/qregexp/main.cpp b/tests/benchmarks/corelib/text/qregexp/main.cpp
new file mode 100644
index 0000000000..798b23f2b0
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qregexp/main.cpp
@@ -0,0 +1,615 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QRegExp>
+#include <QString>
+#include <QFile>
+
+#include <qtest.h>
+#ifdef HAVE_BOOST
+#include <boost/regex.hpp>
+#endif
+
+#ifdef HAVE_JSC
+#include <QtScript>
+#include "pcre/pcre.h"
+#endif
+#define ZLIB_VERSION "1.2.3.4"
+
+class tst_qregexp : public QObject
+{
+ Q_OBJECT
+public:
+ tst_qregexp();
+private slots:
+ void escape_old();
+ void escape_old_data() { escape_data(); }
+ void escape_new1();
+ void escape_new1_data() { escape_data(); }
+ void escape_new2();
+ void escape_new2_data() { escape_data(); }
+ void escape_new3();
+ void escape_new3_data() { escape_data(); }
+ void escape_new4();
+ void escape_new4_data() { escape_data(); }
+/*
+ JSC outperforms everything.
+ Boost is less impressive then expected.
+ */
+ void simpleFind1();
+ void rangeReplace1();
+ void matchReplace1();
+
+ void simpleFind2();
+ void rangeReplace2();
+ void matchReplace2();
+
+ void simpleFindJSC();
+ void rangeReplaceJSC();
+ void matchReplaceJSC();
+
+ void simpleFindBoost();
+ void rangeReplaceBoost();
+ void matchReplaceBoost();
+
+/* those apply an (incorrect) regexp on entire source
+ (this main.cpp). JSC appears to handle this
+ (ab)use case best. QRegExp performs extremly bad.
+ */
+ void horribleWrongReplace1();
+ void horribleReplace1();
+ void horribleReplace2();
+ void horribleWrongReplace2();
+ void horribleWrongReplaceJSC();
+ void horribleReplaceJSC();
+ void horribleWrongReplaceBoost();
+ void horribleReplaceBoost();
+private:
+ QString str1;
+ QString str2;
+ void escape_data();
+};
+
+tst_qregexp::tst_qregexp()
+ :QObject()
+ ,str1("We are all happy monkeys")
+{
+ QFile f(":/main.cpp");
+ f.open(QFile::ReadOnly);
+ str2=f.readAll();
+}
+
+static void verify(const QString &quoted, const QString &expected)
+{
+ if (quoted != expected)
+ qDebug() << "ERROR:" << quoted << expected;
+}
+
+void tst_qregexp::escape_data()
+{
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<QString>("expected");
+
+ QTest::newRow("escape 0") << "Hello world" << "Hello world";
+ QTest::newRow("escape 1") << "(Hello world)" << "\\(Hello world\\)";
+ {
+ QString s;
+ for (int i = 0; i < 10; ++i)
+ s += "(escape)";
+ QTest::newRow("escape 10") << s << QRegExp::escape(s);
+ }
+ {
+ QString s;
+ for (int i = 0; i < 100; ++i)
+ s += "(escape)";
+ QTest::newRow("escape 100") << s << QRegExp::escape(s);
+ }
+}
+
+void tst_qregexp::escape_old()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, expected);
+
+ QBENCHMARK {
+ static const char meta[] = "$()*+.?[\\]^{|}";
+ QString quoted = pattern;
+ int i = 0;
+
+ while (i < quoted.length()) {
+ if (strchr(meta, quoted.at(i).toLatin1()) != 0)
+ quoted.insert(i++, QLatin1Char('\\'));
+ ++i;
+ }
+
+ verify(quoted, expected);
+ }
+}
+
+void tst_qregexp::escape_new1()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, expected);
+
+ QBENCHMARK {
+ QString quoted;
+ const int count = pattern.count();
+ quoted.reserve(count * 2);
+ const QLatin1Char backslash('\\');
+ for (int i = 0; i < count; i++) {
+ switch (pattern.at(i).toLatin1()) {
+ case '$':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case '.':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ quoted.append(backslash);
+ }
+ quoted.append(pattern.at(i));
+ }
+ verify(quoted, expected);
+ }
+}
+
+void tst_qregexp::escape_new2()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, expected);
+
+ QBENCHMARK {
+ int count = pattern.count();
+ const QLatin1Char backslash('\\');
+ QString quoted(count * 2, backslash);
+ const QChar *patternData = pattern.data();
+ QChar *quotedData = quoted.data();
+ int escaped = 0;
+ for ( ; --count >= 0; ++patternData) {
+ const QChar c = *patternData;
+ switch (c.unicode()) {
+ case '$':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case '.':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ ++escaped;
+ ++quotedData;
+ }
+ *quotedData = c;
+ ++quotedData;
+ }
+ quoted.resize(pattern.size() + escaped);
+
+ verify(quoted, expected);
+ }
+}
+
+void tst_qregexp::escape_new3()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, expected);
+
+ QBENCHMARK {
+ QString quoted;
+ const int count = pattern.count();
+ quoted.reserve(count * 2);
+ const QLatin1Char backslash('\\');
+ for (int i = 0; i < count; i++) {
+ switch (pattern.at(i).toLatin1()) {
+ case '$':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case '.':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ quoted += backslash;
+ }
+ quoted += pattern.at(i);
+ }
+
+ verify(quoted, expected);
+ }
+}
+
+
+static inline bool needsEscaping(int c)
+{
+ switch (c) {
+ case '$':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case '.':
+ case '?':
+ case '[':
+ case '\\':
+ case ']':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ return true;
+ }
+ return false;
+}
+
+void tst_qregexp::escape_new4()
+{
+ QFETCH(QString, pattern);
+ QFETCH(QString, expected);
+
+ QBENCHMARK {
+ const int n = pattern.size();
+ const QChar *patternData = pattern.data();
+ // try to prevent copy if no escape is needed
+ int i = 0;
+ for (int i = 0; i != n; ++i) {
+ const QChar c = patternData[i];
+ if (needsEscaping(c.unicode()))
+ break;
+ }
+ if (i == n) {
+ verify(pattern, expected);
+ // no escaping needed, "return pattern" should be done here.
+ return;
+ }
+ const QLatin1Char backslash('\\');
+ QString quoted(n * 2, backslash);
+ QChar *quotedData = quoted.data();
+ for (int j = 0; j != i; ++j)
+ *quotedData++ = *patternData++;
+ int escaped = 0;
+ for (; i != n; ++i) {
+ const QChar c = *patternData;
+ if (needsEscaping(c.unicode())) {
+ ++escaped;
+ ++quotedData;
+ }
+ *quotedData = c;
+ ++quotedData;
+ ++patternData;
+ }
+ quoted.resize(n + escaped);
+ verify(quoted, expected);
+ // "return quoted"
+ }
+}
+
+
+void tst_qregexp::simpleFind1()
+{
+ int roff;
+ QRegExp rx("happy");
+ rx.setPatternSyntax(QRegExp::RegExp);
+ QBENCHMARK{
+ roff = rx.indexIn(str1);
+ }
+ QCOMPARE(roff, 11);
+}
+
+void tst_qregexp::rangeReplace1()
+{
+ QString r;
+ QRegExp rx("[a-f]");
+ rx.setPatternSyntax(QRegExp::RegExp);
+ QBENCHMARK{
+ r = QString(str1).replace(rx, "-");
+ }
+ QCOMPARE(r, QString("W- -r- -ll h-ppy monk-ys"));
+}
+
+void tst_qregexp::matchReplace1()
+{
+ QString r;
+ QRegExp rx("[^a-f]*([a-f]+)[^a-f]*");
+ rx.setPatternSyntax(QRegExp::RegExp);
+ QBENCHMARK{
+ r = QString(str1).replace(rx, "\\1");
+ }
+ QCOMPARE(r, QString("eaeaae"));
+}
+
+void tst_qregexp::horribleWrongReplace1()
+{
+ QString r;
+ QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*");
+ rx.setPatternSyntax(QRegExp::RegExp);
+ QBENCHMARK{
+ r = QString(str2).replace(rx, "\\1.\\2.\\3");
+ }
+ QCOMPARE(r, str2);
+}
+
+void tst_qregexp::horribleReplace1()
+{
+ QString r;
+ QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
+ rx.setPatternSyntax(QRegExp::RegExp);
+ QBENCHMARK{
+ r = QString(str2).replace(rx, "\\1.\\2.\\3");
+ }
+ QCOMPARE(r, QString("1.2.3"));
+}
+
+
+void tst_qregexp::simpleFind2()
+{
+ int roff;
+ QRegExp rx("happy");
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QBENCHMARK{
+ roff = rx.indexIn(str1);
+ }
+ QCOMPARE(roff, 11);
+}
+
+void tst_qregexp::rangeReplace2()
+{
+ QString r;
+ QRegExp rx("[a-f]");
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QBENCHMARK{
+ r = QString(str1).replace(rx, "-");
+ }
+ QCOMPARE(r, QString("W- -r- -ll h-ppy monk-ys"));
+}
+
+void tst_qregexp::matchReplace2()
+{
+ QString r;
+ QRegExp rx("[^a-f]*([a-f]+)[^a-f]*");
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QBENCHMARK{
+ r = QString(str1).replace(rx, "\\1");
+ }
+ QCOMPARE(r, QString("eaeaae"));
+}
+
+void tst_qregexp::horribleWrongReplace2()
+{
+ QString r;
+ QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*");
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QBENCHMARK{
+ r = QString(str2).replace(rx, "\\1.\\2.\\3");
+ }
+ QCOMPARE(r, str2);
+}
+
+void tst_qregexp::horribleReplace2()
+{
+ QString r;
+ QRegExp rx(".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*");
+ rx.setPatternSyntax(QRegExp::RegExp2);
+ QBENCHMARK{
+ r = QString(str2).replace(rx, "\\1.\\2.\\3");
+ }
+ QCOMPARE(r, QString("1.2.3"));
+}
+void tst_qregexp::simpleFindJSC()
+{
+#ifdef HAVE_JSC
+ int numr;
+ const char * errmsg=" ";
+ QString rxs("happy");
+ JSRegExp *rx = jsRegExpCompile(rxs.utf16(), rxs.length(), JSRegExpDoNotIgnoreCase, JSRegExpSingleLine, 0, &errmsg);
+ QVERIFY(rx != 0);
+ QString s(str1);
+ int offsetVector[3];
+ QBENCHMARK{
+ numr = jsRegExpExecute(rx, s.utf16(), s.length(), 0, offsetVector, 3);
+ }
+ jsRegExpFree(rx);
+ QCOMPARE(numr, 1);
+ QCOMPARE(offsetVector[0], 11);
+#else
+ QSKIP("JSC is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::rangeReplaceJSC()
+{
+#ifdef HAVE_JSC
+ QScriptValue r;
+ QScriptEngine engine;
+ engine.globalObject().setProperty("s", str1);
+ QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/[a-f]/g, '-') } )");
+ QVERIFY(replaceFunc.isFunction());
+ QBENCHMARK{
+ r = replaceFunc.call(QScriptValue());
+ }
+ QCOMPARE(r.toString(), QString("W- -r- -ll h-ppy monk-ys"));
+#else
+ QSKIP("JSC is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::matchReplaceJSC()
+{
+#ifdef HAVE_JSC
+ QScriptValue r;
+ QScriptEngine engine;
+ engine.globalObject().setProperty("s", str1);
+ QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/[^a-f]*([a-f]+)[^a-f]*/g, '$1') } )");
+ QVERIFY(replaceFunc.isFunction());
+ QBENCHMARK{
+ r = replaceFunc.call(QScriptValue());
+ }
+ QCOMPARE(r.toString(), QString("eaeaae"));
+#else
+ QSKIP("JSC is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::horribleWrongReplaceJSC()
+{
+#ifdef HAVE_JSC
+ QScriptValue r;
+ QScriptEngine engine;
+ engine.globalObject().setProperty("s", str2);
+ QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/.*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*/gm, '$1.$2.$3') } )");
+ QVERIFY(replaceFunc.isFunction());
+ QBENCHMARK{
+ r = replaceFunc.call(QScriptValue());
+ }
+ QCOMPARE(r.toString(), str2);
+#else
+ QSKIP("JSC is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::horribleReplaceJSC()
+{
+#ifdef HAVE_JSC
+ QScriptValue r;
+ QScriptEngine engine;
+ // the m flag doesn't actually work here; dunno
+ engine.globalObject().setProperty("s", str2.replace('\n', ' '));
+ QScriptValue replaceFunc = engine.evaluate("(function() { return s.replace(/.*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*/gm, '$1.$2.$3') } )");
+ QVERIFY(replaceFunc.isFunction());
+ QBENCHMARK{
+ r = replaceFunc.call(QScriptValue());
+ }
+ QCOMPARE(r.toString(), QString("1.2.3"));
+#else
+ QSKIP("JSC is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::simpleFindBoost()
+{
+#ifdef HAVE_BOOST
+ int roff;
+ boost::regex rx ("happy", boost::regex_constants::perl);
+ std::string s = str1.toStdString();
+ std::string::const_iterator start, end;
+ start = s.begin();
+ end = s.end();
+ boost::match_flag_type flags = boost::match_default;
+ QBENCHMARK{
+ boost::match_results<std::string::const_iterator> what;
+ regex_search(start, end, what, rx, flags);
+ roff = (what[0].first)-start;
+ }
+ QCOMPARE(roff, 11);
+#else
+ QSKIP("Boost is not enabled for this platform");
+#endif
+
+}
+
+void tst_qregexp::rangeReplaceBoost()
+{
+#ifdef HAVE_BOOST
+ boost::regex pattern ("[a-f]", boost::regex_constants::perl);
+ std::string s = str1.toStdString();
+ std::string r;
+ QBENCHMARK{
+ r = boost::regex_replace (s, pattern, "-");
+ }
+ QCOMPARE(r, std::string("W- -r- -ll h-ppy monk-ys"));
+#else
+ QSKIP("Boost is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::matchReplaceBoost()
+{
+#ifdef HAVE_BOOST
+ boost::regex pattern ("[^a-f]*([a-f]+)[^a-f]*",boost::regex_constants::perl);
+ std::string s = str1.toStdString();
+ std::string r;
+ QBENCHMARK{
+ r = boost::regex_replace (s, pattern, "$1");
+ }
+ QCOMPARE(r, std::string("eaeaae"));
+#else
+ QSKIP("Boost is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::horribleWrongReplaceBoost()
+{
+#ifdef HAVE_BOOST
+ boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*", boost::regex_constants::perl);
+ std::string s = str2.toStdString();
+ std::string r;
+ QBENCHMARK{
+ r = boost::regex_replace (s, pattern, "$1.$2.$3");
+ }
+ QCOMPARE(r, s);
+#else
+ QSKIP("Boost is not enabled for this platform");
+#endif
+}
+
+void tst_qregexp::horribleReplaceBoost()
+{
+#ifdef HAVE_BOOST
+ boost::regex pattern (".*#""define ZLIB_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+).*", boost::regex_constants::perl);
+ std::string s = str2.toStdString();
+ std::string r;
+ QBENCHMARK{
+ r = boost::regex_replace (s, pattern, "$1.$2.$3");
+ }
+ QCOMPARE(r, std::string("1.2.3"));
+#else
+ QSKIP("Boost is not enabled for this platform");
+#endif
+}
+
+QTEST_MAIN(tst_qregexp)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qregexp/qregexp.pro b/tests/benchmarks/corelib/text/qregexp/qregexp.pro
new file mode 100644
index 0000000000..f64ae781a2
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qregexp/qregexp.pro
@@ -0,0 +1,20 @@
+TEMPLATE = app
+TARGET = tst_bench_qregexp
+QT = core testlib
+CONFIG += release exceptions
+
+SOURCES += main.cpp
+RESOURCES += qregexp.qrc
+
+qtHaveModule(script):!pcre {
+ DEFINES += HAVE_JSC
+ QT += script
+}
+
+!qnx {
+ exists($$[QT_SYSROOT]/usr/include/boost/regex.hpp) {
+ DEFINES += HAVE_BOOST
+ LIBS += -lboost_regex
+ }
+}
+
diff --git a/tests/benchmarks/corelib/text/qregexp/qregexp.qrc b/tests/benchmarks/corelib/text/qregexp/qregexp.qrc
new file mode 100644
index 0000000000..a7fe13c035
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qregexp/qregexp.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>main.cpp</file>
+</qresource>
+</RCC>
+
diff --git a/tests/benchmarks/corelib/text/qstring/main.cpp b/tests/benchmarks/corelib/text/qstring/main.cpp
new file mode 100644
index 0000000000..826a843c10
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstring/main.cpp
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QStringList>
+#include <QFile>
+#include <QtTest/QtTest>
+
+class tst_QString: public QObject
+{
+ Q_OBJECT
+public:
+ tst_QString();
+private slots:
+ void section_regexp_data() { section_data_impl(); }
+ void section_regexp() { section_impl<QRegExp>(); }
+ void section_regularexpression_data() { section_data_impl(); }
+ void section_regularexpression() { section_impl<QRegularExpression>(); }
+ void section_string_data() { section_data_impl(false); }
+ void section_string() { section_impl<QString>(); }
+
+ void toUpper_data();
+ void toUpper();
+ void toLower_data();
+ void toLower();
+ void toCaseFolded_data();
+ void toCaseFolded();
+
+private:
+ void section_data_impl(bool includeRegExOnly = true);
+ template <typename RX> void section_impl();
+};
+
+tst_QString::tst_QString()
+{
+}
+
+void tst_QString::section_data_impl(bool includeRegExOnly)
+{
+ QTest::addColumn<QString>("s");
+ QTest::addColumn<QString>("sep");
+ QTest::addColumn<bool>("isRegExp");
+
+ QTest::newRow("IPv4") << QStringLiteral("192.168.0.1") << QStringLiteral(".") << false;
+ QTest::newRow("IPv6") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral(":") << false;
+ if (includeRegExOnly) {
+ QTest::newRow("IPv6-reversed-roles") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("\\d+") << true;
+ QTest::newRow("IPv6-complex") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("(\\d+):\\1") << true;
+ }
+}
+
+template <typename RX>
+inline QString escape(const QString &s)
+{ return RX::escape(s); }
+
+template <>
+inline QString escape<QString>(const QString &s)
+{ return s; }
+
+template <typename RX>
+inline void optimize(RX &) {}
+
+template <>
+inline void optimize(QRegularExpression &rx)
+{ rx.optimize(); }
+
+template <typename RX>
+void tst_QString::section_impl()
+{
+ QFETCH(QString, s);
+ QFETCH(QString, sep);
+ QFETCH(bool, isRegExp);
+
+ RX rx(isRegExp ? sep : escape<RX>(sep));
+ optimize(rx);
+ for (int i = 0; i < 20; ++i)
+ (void) s.count(rx); // make (s, rx) hot
+
+ QBENCHMARK {
+ const QString result = s.section(rx, 0, 16);
+ Q_UNUSED(result);
+ }
+}
+
+void tst_QString::toUpper_data()
+{
+ QTest::addColumn<QString>("s");
+
+ QString lowerLatin1(300, QChar('a'));
+ QString upperLatin1(300, QChar('A'));
+
+ QString lowerDeseret;
+ {
+ QString pattern;
+ pattern += QChar(QChar::highSurrogate(0x10428));
+ pattern += QChar(QChar::lowSurrogate(0x10428));
+ for (int i = 0; i < 300 / pattern.size(); ++i)
+ lowerDeseret += pattern;
+ }
+ QString upperDeseret;
+ {
+ QString pattern;
+ pattern += QChar(QChar::highSurrogate(0x10400));
+ pattern += QChar(QChar::lowSurrogate(0x10400));
+ for (int i = 0; i < 300 / pattern.size(); ++i)
+ upperDeseret += pattern;
+ }
+
+ QString lowerLigature(600, QChar(0xFB03));
+
+ QTest::newRow("600<a>") << (lowerLatin1 + lowerLatin1);
+ QTest::newRow("600<A>") << (upperLatin1 + upperLatin1);
+
+ QTest::newRow("300<a>+300<A>") << (lowerLatin1 + upperLatin1);
+ QTest::newRow("300<A>+300<a>") << (upperLatin1 + lowerLatin1);
+
+ QTest::newRow("300<10428>") << (lowerDeseret + lowerDeseret);
+ QTest::newRow("300<10400>") << (upperDeseret + upperDeseret);
+
+ QTest::newRow("150<10428>+150<10400>") << (lowerDeseret + upperDeseret);
+ QTest::newRow("150<10400>+150<10428>") << (upperDeseret + lowerDeseret);
+
+ QTest::newRow("300a+150<10400>") << (lowerLatin1 + upperDeseret);
+ QTest::newRow("300a+150<10428>") << (lowerLatin1 + lowerDeseret);
+ QTest::newRow("300A+150<10400>") << (upperLatin1 + upperDeseret);
+ QTest::newRow("300A+150<10428>") << (upperLatin1 + lowerDeseret);
+
+ QTest::newRow("600<FB03> (ligature)") << lowerLigature;
+}
+
+void tst_QString::toUpper()
+{
+ QFETCH(QString, s);
+
+ QBENCHMARK {
+ s.toUpper();
+ }
+}
+
+void tst_QString::toLower_data()
+{
+ toUpper_data();
+}
+
+void tst_QString::toLower()
+{
+ QFETCH(QString, s);
+
+ QBENCHMARK {
+ s.toLower();
+ }
+}
+
+void tst_QString::toCaseFolded_data()
+{
+ toUpper_data();
+}
+
+void tst_QString::toCaseFolded()
+{
+ QFETCH(QString, s);
+
+ QBENCHMARK {
+ s.toCaseFolded();
+ }
+}
+
+QTEST_APPLESS_MAIN(tst_QString)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qstring/qstring.pro b/tests/benchmarks/corelib/text/qstring/qstring.pro
new file mode 100644
index 0000000000..9f5e34b915
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstring/qstring.pro
@@ -0,0 +1,5 @@
+TARGET = tst_bench_qstring
+QT -= gui
+QT += core testlib
+SOURCES += main.cpp
+
diff --git a/tests/benchmarks/corelib/text/qstringbuilder/main.cpp b/tests/benchmarks/corelib/text/qstringbuilder/main.cpp
new file mode 100644
index 0000000000..0de6d33846
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstringbuilder/main.cpp
@@ -0,0 +1,420 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Select one of the scenarios below
+#define SCENARIO 1
+
+#if SCENARIO == 1
+// this is the "no harm done" version. Only operator% is active,
+// with NO_CAST * defined
+#define P %
+#undef QT_USE_FAST_OPERATOR_PLUS
+#undef QT_USE_FAST_CONCATENATION
+#define QT_NO_CAST_FROM_ASCII
+#define QT_NO_CAST_TO_ASCII
+#endif
+
+
+#if SCENARIO == 2
+// this is the "full" version. Operator+ is replaced by a QStringBuilder
+// based version
+// with NO_CAST * defined
+#define P +
+#define QT_USE_FAST_OPERATOR_PLUS
+#define QT_USE_FAST_CONCATENATION
+#define QT_NO_CAST_FROM_ASCII
+#define QT_NO_CAST_TO_ASCII
+#endif
+
+#if SCENARIO == 3
+// this is the "no harm done" version. Only operator% is active,
+// with NO_CAST * _not_ defined
+#define P %
+#undef QT_USE_FAST_OPERATOR_PLUS
+#undef QT_USE_FAST_CONCATENATION
+#undef QT_NO_CAST_FROM_ASCII
+#undef QT_NO_CAST_TO_ASCII
+#endif
+
+#if SCENARIO == 4
+// this is the "full" version. Operator+ is replaced by a QStringBuilder
+// based version
+// with NO_CAST * _not_ defined
+#define P +
+#define QT_USE_FAST_OPERATOR_PLUS
+#define QT_USE_FAST_CONCATENATION
+#undef QT_NO_CAST_FROM_ASCII
+#undef QT_NO_CAST_TO_ASCII
+#endif
+
+
+#include <qbytearray.h>
+#include <qdebug.h>
+#include <qstring.h>
+#include <qstringbuilder.h>
+
+#include <qtest.h>
+
+#include <string>
+
+#define COMPARE(a, b) QCOMPARE(a, b)
+//#define COMPARE(a, b)
+
+#define SEP(s) qDebug() << "\n\n-------- " s " ---------";
+
+#define LITERAL "some string literal"
+
+class tst_qstringbuilder : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_qstringbuilder()
+ : l1literal(LITERAL),
+ l1string(LITERAL),
+ ba(LITERAL),
+ string(l1string),
+ stdstring(LITERAL),
+ stringref(&string, 2, 10),
+ achar('c'),
+ r2(QLatin1String(LITERAL LITERAL)),
+ r3(QLatin1String(LITERAL LITERAL LITERAL)),
+ r4(QLatin1String(LITERAL LITERAL LITERAL LITERAL)),
+ r5(QLatin1String(LITERAL LITERAL LITERAL LITERAL LITERAL))
+ {}
+
+
+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 P l1literal).size();
+ s += QString(l1literal P l1literal P l1literal).size();
+ s += QString(l1literal P l1literal P l1literal P l1literal).size();
+ s += QString(l1literal P l1literal P l1literal P l1literal P l1literal).size();
+#endif
+ s += QString(achar % l1literal % achar).size();
+ }
+ return s;
+ }
+
+private slots:
+
+ void separator_0() {
+ qDebug() << "\nIn each block the QStringBuilder based result appear first "
+ "(with a 'b_' prefix), QStringBased second ('q_' prefix), std::string "
+ "last ('s_' prefix)\n";
+ }
+
+ void separator_1() { SEP("literal + literal (builder first)"); }
+
+ void b_2_l1literal() {
+ QBENCHMARK { r = l1literal P l1literal; }
+ COMPARE(r, r2);
+ }
+ #ifndef QT_NO_CAST_FROM_ASCII
+ void b_l1literal_LITERAL() {
+ QBENCHMARK { r = l1literal P LITERAL; }
+ COMPARE(r, r2);
+ }
+ #endif
+ void q_2_l1string() {
+ QBENCHMARK { r = l1string + l1string; }
+ COMPARE(r, r2);
+ }
+
+
+ void separator_2() { SEP("2 strings"); }
+
+ void b_2_string() {
+ QBENCHMARK { r = string P string; }
+ COMPARE(r, r2);
+ }
+ void q_2_string() {
+ QBENCHMARK { r = string + string; }
+ COMPARE(r, r2);
+ }
+ void s_2_string() {
+ QBENCHMARK { stdr = stdstring + stdstring; }
+ COMPARE(stdr, stdstring + stdstring);
+ }
+
+
+ void separator_2c() { SEP("2 string refs"); }
+
+ void b_2_stringref() {
+ QBENCHMARK { r = stringref % stringref; }
+ COMPARE(r, QString(stringref.toString() + stringref.toString()));
+ }
+ void q_2_stringref() {
+ QBENCHMARK { r = stringref.toString() + stringref.toString(); }
+ COMPARE(r, QString(stringref % stringref));
+ }
+
+
+ void separator_2b() { SEP("3 strings"); }
+
+ void b_3_string() {
+ QBENCHMARK { r = string P string P string; }
+ COMPARE(r, r3);
+ }
+ void q_3_string() {
+ QBENCHMARK { r = string + string + string; }
+ COMPARE(r, r3);
+ }
+ void s_3_string() {
+ QBENCHMARK { stdr = stdstring + stdstring + stdstring; }
+ COMPARE(stdr, stdstring + stdstring + stdstring);
+ }
+
+ void separator_2e() { SEP("4 strings"); }
+
+ void b_4_string() {
+ QBENCHMARK { r = string P string P string P string; }
+ COMPARE(r, r4);
+ }
+ void q_4_string() {
+ QBENCHMARK { r = string + string + string + string; }
+ COMPARE(r, r4);
+ }
+ void s_4_string() {
+ QBENCHMARK { stdr = stdstring + stdstring + stdstring + stdstring; }
+ COMPARE(stdr, stdstring + stdstring + stdstring + stdstring);
+ }
+
+
+
+ void separator_2a() { SEP("string + literal (builder first)"); }
+
+ void b_string_l1literal() {
+ QBENCHMARK { r = string % l1literal; }
+ COMPARE(r, r2);
+ }
+ #ifndef QT_NO_CAST_FROM_ASCII
+ void b_string_LITERAL() {
+ QBENCHMARK { r = string P LITERAL; }
+ COMPARE(r, r2);
+ }
+ void b_LITERAL_string() {
+ QBENCHMARK { r = LITERAL P string; }
+ COMPARE(r, r2);
+ }
+ #endif
+ void b_string_l1string() {
+ QBENCHMARK { r = string P l1string; }
+ COMPARE(r, r2);
+ }
+ void q_string_l1literal() {
+ QBENCHMARK { r = string + l1string; }
+ COMPARE(r, r2);
+ }
+ void q_string_l1string() {
+ QBENCHMARK { r = string + l1string; }
+ COMPARE(r, r2);
+ }
+ void s_LITERAL_string() {
+ QBENCHMARK { stdr = LITERAL + stdstring; }
+ COMPARE(stdr, stdstring + stdstring);
+ }
+
+
+ void separator_3() { SEP("3 literals"); }
+
+ void b_3_l1literal() {
+ QBENCHMARK { r = l1literal P l1literal P l1literal; }
+ COMPARE(r, r3);
+ }
+ void q_3_l1string() {
+ QBENCHMARK { r = l1string + l1string + l1string; }
+ COMPARE(r, r3);
+ }
+ void s_3_l1string() {
+ QBENCHMARK { stdr = stdstring + LITERAL + LITERAL; }
+ COMPARE(stdr, stdstring + stdstring + stdstring);
+ }
+
+
+ void separator_4() { SEP("4 literals"); }
+
+ void b_4_l1literal() {
+ QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal; }
+ COMPARE(r, r4);
+ }
+ void q_4_l1string() {
+ QBENCHMARK { r = l1string + l1string + l1string + l1string; }
+ COMPARE(r, r4);
+ }
+
+
+ void separator_5() { SEP("5 literals"); }
+
+ void b_5_l1literal() {
+ QBENCHMARK { r = l1literal P l1literal P l1literal P l1literal P l1literal; }
+ COMPARE(r, r5);
+ }
+
+ void q_5_l1string() {
+ QBENCHMARK { r = l1string + l1string + l1string + l1string + l1string; }
+ COMPARE(r, r5);
+ }
+
+
+ void separator_6() { SEP("4 chars"); }
+
+ void b_string_4_char() {
+ QBENCHMARK { r = string + achar + achar + achar + achar; }
+ COMPARE(r, QString(string P achar P achar P achar P achar));
+ }
+
+ void q_string_4_char() {
+ QBENCHMARK { r = string + achar + achar + achar + achar; }
+ COMPARE(r, QString(string P achar P achar P achar P achar));
+ }
+
+ void s_string_4_char() {
+ QBENCHMARK { stdr = stdstring + 'c' + 'c' + 'c' + 'c'; }
+ COMPARE(stdr, stdstring + 'c' + 'c' + 'c' + 'c');
+ }
+
+
+ void separator_7() { SEP("char + string + char"); }
+
+ void b_char_string_char() {
+ QBENCHMARK { r = achar + string + achar; }
+ COMPARE(r, QString(achar P string P achar));
+ }
+
+ void q_char_string_char() {
+ QBENCHMARK { r = achar + string + achar; }
+ COMPARE(r, QString(achar P string P achar));
+ }
+
+ void s_char_string_char() {
+ QBENCHMARK { stdr = 'c' + stdstring + 'c'; }
+ COMPARE(stdr, 'c' + stdstring + 'c');
+ }
+
+
+ void separator_8() { SEP("string.arg"); }
+
+ void b_string_arg() {
+ const QString pattern = l1string + QString::fromLatin1("%1") + l1string;
+ QBENCHMARK { r = l1literal P string P l1literal; }
+ COMPARE(r, r3);
+ }
+
+ void q_string_arg() {
+ const QString pattern = l1string + QLatin1String("%1") + l1string;
+ QBENCHMARK { r = pattern.arg(string); }
+ COMPARE(r, r3);
+ }
+
+ void q_bytearray_arg() {
+ QByteArray result;
+ QBENCHMARK { result = ba + ba + ba; }
+ }
+
+
+ void separator_9() { SEP("QString::reserve()"); }
+
+ void b_reserve() {
+ QBENCHMARK {
+ r.clear();
+ r = string P string P string P string;
+ }
+ COMPARE(r, r4);
+ }
+ void b_reserve_lit() {
+ QBENCHMARK {
+ r.clear();
+ r = string P l1literal P string P string;
+ }
+ COMPARE(r, r4);
+ }
+ void s_reserve() {
+ QBENCHMARK {
+ r.clear();
+ r.reserve(string.size() + string.size() + string.size() + string.size());
+ r += string;
+ r += string;
+ r += string;
+ r += string;
+ }
+ COMPARE(r, r4);
+ }
+ void s_reserve_lit() {
+ QBENCHMARK {
+ r.clear();
+ //r.reserve(string.size() + qstrlen(l1string.latin1())
+ // + string.size() + string.size());
+ r.reserve(1024);
+ r += string;
+ r += l1string;
+ r += string;
+ r += string;
+ }
+ COMPARE(r, r4);
+ }
+
+private:
+ const QLatin1String l1literal;
+ const QLatin1String l1string;
+ const QByteArray ba;
+ const QString string;
+ const std::string stdstring;
+ const QStringRef stringref;
+ const QLatin1Char achar;
+ const QString r2, r3, r4, r5;
+
+ // short cuts for results
+ QString r;
+ std::string stdr;
+};
+
+QTEST_MAIN(tst_qstringbuilder)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro b/tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro
new file mode 100644
index 0000000000..fa4cbe3c13
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstringbuilder/qstringbuilder.pro
@@ -0,0 +1,11 @@
+TEMPLATE = app
+TARGET = tst_bench_qstringbuilder
+
+QMAKE_CXXFLAGS += -g
+QMAKE_CFLAGS += -g
+
+QT = core testlib
+
+CONFIG += release
+
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/text/qstringlist/.gitignore b/tests/benchmarks/corelib/text/qstringlist/.gitignore
new file mode 100644
index 0000000000..3e0cdc952f
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstringlist/.gitignore
@@ -0,0 +1 @@
+tst_qstringlist
diff --git a/tests/benchmarks/corelib/text/qstringlist/main.cpp b/tests/benchmarks/corelib/text/qstringlist/main.cpp
new file mode 100644
index 0000000000..ae355a8b89
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstringlist/main.cpp
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QStringList>
+#include <QtTest>
+
+#include <sstream>
+#include <string>
+#include <vector>
+
+class tst_QStringList: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void join() const;
+ void join_data() const;
+
+ void split_qlist_qbytearray() const;
+ void split_qlist_qbytearray_data() const { return split_data(); }
+
+ void split_data() const;
+ void split_qlist_qstring() const;
+ void split_qlist_qstring_data() const { return split_data(); }
+
+ void split_stdvector_stdstring() const;
+ void split_stdvector_stdstring_data() const { return split_data(); }
+
+ void split_stdvector_stdwstring() const;
+ void split_stdvector_stdwstring_data() const { return split_data(); }
+
+ void split_stdlist_stdstring() const;
+ void split_stdlist_stdstring_data() const { return split_data(); }
+
+private:
+ static QStringList populateList(const int count, const QString &unit);
+ static QString populateString(const int count, const QString &unit);
+};
+
+QStringList tst_QStringList::populateList(const int count, const QString &unit)
+{
+ QStringList retval;
+
+ for (int i = 0; i < count; ++i)
+ retval.append(unit);
+
+ return retval;
+}
+
+QString tst_QStringList::populateString(const int count, const QString &unit)
+{
+ QString retval;
+
+ for (int i = 0; i < count; ++i) {
+ retval.append(unit);
+ retval.append(QLatin1Char(':'));
+ }
+
+ return retval;
+}
+
+void tst_QStringList::join() const
+{
+ QFETCH(QStringList, input);
+ QFETCH(QString, separator);
+
+ QBENCHMARK {
+ input.join(separator);
+ }
+}
+
+void tst_QStringList::join_data() const
+{
+ QTest::addColumn<QStringList>("input");
+ QTest::addColumn<QString>("separator");
+
+ QTest::newRow("")
+ << populateList(100, QLatin1String("unit"))
+ << QString();
+
+ QTest::newRow("")
+ << populateList(1000, QLatin1String("unit"))
+ << QString();
+
+ QTest::newRow("")
+ << populateList(10000, QLatin1String("unit"))
+ << QString();
+
+ QTest::newRow("")
+ << populateList(100000, QLatin1String("unit"))
+ << QString();
+}
+
+void tst_QStringList::split_data() const
+{
+ QTest::addColumn<QString>("input");
+ QString unit = QLatin1String("unit") + QString(100, QLatin1Char('s'));
+ //QTest::newRow("") << populateString(10, unit);
+ QTest::newRow("") << populateString(100, unit);
+ //QTest::newRow("") << populateString(100, unit);
+ //QTest::newRow("") << populateString(1000, unit);
+ //QTest::newRow("") << populateString(10000, unit);
+}
+
+void tst_QStringList::split_qlist_qbytearray() const
+{
+ QFETCH(QString, input);
+ const char splitChar = ':';
+ QByteArray ba = input.toLatin1();
+
+ QBENCHMARK {
+ ba.split(splitChar);
+ }
+}
+
+void tst_QStringList::split_qlist_qstring() const
+{
+ QFETCH(QString, input);
+ const QChar splitChar = ':';
+
+ QBENCHMARK {
+ input.split(splitChar);
+ }
+}
+
+void tst_QStringList::split_stdvector_stdstring() const
+{
+ QFETCH(QString, input);
+ const char split_char = ':';
+ std::string stdinput = input.toStdString();
+
+ QBENCHMARK {
+ std::istringstream split(stdinput);
+ std::vector<std::string> token;
+ for (std::string each;
+ std::getline(split, each, split_char);
+ token.push_back(each))
+ ;
+ }
+}
+
+void tst_QStringList::split_stdvector_stdwstring() const
+{
+ QFETCH(QString, input);
+ const wchar_t split_char = ':';
+ std::wstring stdinput = input.toStdWString();
+
+ QBENCHMARK {
+ std::wistringstream split(stdinput);
+ std::vector<std::wstring> token;
+ for (std::wstring each;
+ std::getline(split, each, split_char);
+ token.push_back(each))
+ ;
+ }
+}
+
+void tst_QStringList::split_stdlist_stdstring() const
+{
+ QFETCH(QString, input);
+ const char split_char = ':';
+ std::string stdinput = input.toStdString();
+
+ QBENCHMARK {
+ std::istringstream split(stdinput);
+ std::list<std::string> token;
+ for (std::string each;
+ std::getline(split, each, split_char);
+ token.push_back(each))
+ ;
+ }
+}
+
+QTEST_MAIN(tst_QStringList)
+
+#include "main.moc"
diff --git a/tests/benchmarks/corelib/text/qstringlist/qstringlist.pro b/tests/benchmarks/corelib/text/qstringlist/qstringlist.pro
new file mode 100644
index 0000000000..5803e7da0e
--- /dev/null
+++ b/tests/benchmarks/corelib/text/qstringlist/qstringlist.pro
@@ -0,0 +1,5 @@
+TARGET = tst_bench_qstringlist
+CONFIG -= debug
+CONFIG += release
+QT = core testlib
+SOURCES += main.cpp
diff --git a/tests/benchmarks/corelib/text/text.pro b/tests/benchmarks/corelib/text/text.pro
new file mode 100644
index 0000000000..a2397b37fe
--- /dev/null
+++ b/tests/benchmarks/corelib/text/text.pro
@@ -0,0 +1,9 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ qbytearray \
+ qchar \
+ qlocale \
+ qstringbuilder \
+ qstringlist
+
+*g++*: SUBDIRS += qstring