summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2022-11-02 13:56:00 +0100
committerEdward Welbourne <edward.welbourne@qt.io>2022-11-11 16:32:52 +0100
commitcf36db4df9d4f760f6cb41f49921aee64f06ef10 (patch)
treefd26d3c41397d8215e0083f39804908765b0878e /tests
parent7fef433004f7ebde47c1ac80d98c6abac82f2eea (diff)
Add benchmarks for QLocale number parsing
Based on those for QString, but with locale variation and exercising some of the locales with multi-character signs and exponents. Pick-to: 6.4 6.2 5.15 Change-Id: Id0253449f9abcc154285f89337aa0e26dd69900d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/benchmarks/corelib/text/qlocale/tst_bench_qlocale.cpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/tests/benchmarks/corelib/text/qlocale/tst_bench_qlocale.cpp b/tests/benchmarks/corelib/text/qlocale/tst_bench_qlocale.cpp
index c32a78f5bd..8e0c559dbe 100644
--- a/tests/benchmarks/corelib/text/qlocale/tst_bench_qlocale.cpp
+++ b/tests/benchmarks/corelib/text/qlocale/tst_bench_qlocale.cpp
@@ -4,6 +4,8 @@
#include <QLocale>
#include <QTest>
+using namespace Qt::StringLiterals;
+
class tst_QLocale : public QObject
{
Q_OBJECT
@@ -29,6 +31,12 @@ private Q_SLOTS:
void toUpper_QLocale_2();
void toUpper_QString();
void number_QString();
+ void toLongLong_data();
+ void toLongLong();
+ void toULongLong_data();
+ void toULongLong();
+ void toDouble_data();
+ void toDouble();
};
static QString data()
@@ -367,6 +375,228 @@ void tst_QLocale::number_QString()
}
}
+template <typename Integer>
+void toWholeCommon_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<Integer>("expected");
+
+ QTest::newRow("C: empty") << u""_s << u"C"_s << false << Integer(0ull);
+ QTest::newRow("C: 0") << u"0"_s << u"C"_s << true << Integer(0ull);
+ QTest::newRow("C: 1234") << u"1234"_s << u"C"_s << true << Integer(1234ull);
+ // C locale omits grouping, but doesn't reject it.
+ QTest::newRow("C: 1,234") << u"1,234"_s << u"C"_s << true << Integer(1234ull);
+ QTest::newRow("C: 123456789")
+ << u"123456789"_s << u"C"_s << true << Integer(123456789ull);
+ QTest::newRow("C: 123,456,789")
+ << u"123,456,789"_s << u"C"_s << true << Integer(123456789ull);
+
+ QTest::newRow("en: empty") << u""_s << u"en"_s << false << Integer(0ull);
+ QTest::newRow("en: 0") << u"0"_s << u"en"_s << true << Integer(0ull);
+ QTest::newRow("en: 1234") << u"1234"_s << u"en"_s << true << Integer(1234ull);
+ QTest::newRow("en: 1,234") << u"1,234"_s << u"en"_s << true << Integer(1234ull);
+ QTest::newRow("en: 123,456,789")
+ << u"123,456,789"_s << u"en"_s << true << Integer(123456789ull);
+ QTest::newRow("en: 123456789")
+ << u"123456789"_s << u"en"_s << true << Integer(123456789ull);
+
+ QTest::newRow("de: empty") << u""_s << u"de"_s << false << Integer(0ull);
+ QTest::newRow("de: 0") << u"0"_s << u"de"_s << true << Integer(0ull);
+ QTest::newRow("de: 1234") << u"1234"_s << u"de"_s << true << Integer(1234ull);
+ QTest::newRow("de: 1.234") << u"1.234"_s << u"de"_s << true << Integer(1234ull);
+ QTest::newRow("de: 123.456.789")
+ << u"123.456.789"_s << u"de"_s << true << Integer(123456789ull);
+ QTest::newRow("de: 123456789")
+ << u"123456789"_s << u"de"_s << true << Integer(123456789ull);
+
+ // Locales with non-single-character signs:
+ QTest::newRow("ar_EG: +403") // Arabic, Egypt
+ << u"\u061c+\u0664\u0660\u0663"_s << u"ar_EG"_s << true << Integer(403ull);
+ QTest::newRow("ar_EG: !403") // Only first character of the sign
+ << u"\u061c\u0664\u0660\u0663"_s << u"ar_EG"_s << false << Integer(0ull);
+ QTest::newRow("fa_IR: +403") // Farsi, Iran
+ << u"\u200e+\u06f4\u06f0\u06f3"_s << u"fa_IR"_s << true << Integer(403ull);
+ QTest::newRow("fa_IR: !403") // Only first character of sign
+ << u"\u200e\u06f4\u06f0\u06f3"_s << u"fa_IR"_s << false << Integer(0ull);
+}
+
+void tst_QLocale::toLongLong_data()
+{
+ toWholeCommon_data<qlonglong>();
+
+ QTest::newRow("C: -1234") << u"-1234"_s << u"C"_s << true << -1234ll;
+ QTest::newRow("C: -123456789") << u"-123456789"_s << u"C"_s << true << -123456789ll;
+ QTest::newRow("C: qlonglong-max")
+ << u"9223372036854775807"_s << u"C"_s << true
+ << std::numeric_limits<qlonglong>::max();
+ QTest::newRow("C: qlonglong-min")
+ << u"-9223372036854775808"_s << u"C"_s << true
+ << std::numeric_limits<qlonglong>::min();
+
+ // Locales with multi-character signs:
+ QTest::newRow("ar_EG: -403") // Arabic, Egypt
+ << u"\u061c-\u0664\u0660\u0663"_s << u"ar_EG"_s << true << -403ll;
+ QTest::newRow("fa_IR: -403") // Farsi, Iran
+ << u"\u200e\u2212\u06f4\u06f0\u06f3"_s << u"fa_IR"_s << true << -403ll;
+}
+
+void tst_QLocale::toLongLong()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, locale);
+ QFETCH(bool, good);
+ QFETCH(qlonglong, expected);
+
+ const QLocale loc(locale);
+ qlonglong actual = expected;
+ bool ok = false;
+ QBENCHMARK {
+ actual = loc.toLongLong(text, &ok);
+ }
+ QEXPECT_FAIL("ar_EG: +403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("ar_EG: -403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("fa_IR: +403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("fa_IR: -403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QCOMPARE(ok, good);
+ QCOMPARE(actual, expected);
+}
+
+void tst_QLocale::toULongLong_data()
+{
+ toWholeCommon_data<qulonglong>();
+
+ QTest::newRow("C: qlonglong-max + 1")
+ << u"9223372036854775808"_s << u"C"_s << true
+ << (qulonglong(std::numeric_limits<qlonglong>::max()) + 1);
+ QTest::newRow("C: qulonglong-max")
+ << u"18446744073709551615"_s << u"C"_s << true
+ << std::numeric_limits<qulonglong>::max();
+}
+
+void tst_QLocale::toULongLong()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, locale);
+ QFETCH(bool, good);
+ QFETCH(qulonglong, expected);
+
+ const QLocale loc(locale);
+ qulonglong actual = expected;
+ bool ok = false;
+ QBENCHMARK {
+ actual = loc.toULongLong(text, &ok);
+ }
+ QEXPECT_FAIL("ar_EG: +403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("fa_IR: +403", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QCOMPARE(ok, good);
+ QCOMPARE(actual, expected);
+}
+
+
+void tst_QLocale::toDouble_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<bool>("good");
+ QTest::addColumn<double>("expected");
+
+ QTest::newRow("C: empty") << u""_s << u"C"_s << false << 0.0;
+ QTest::newRow("C: 0") << u"0"_s << u"C"_s << true << 0.0;
+ QTest::newRow("C: 0.12340") << u"0.12340"_s << u"C"_s << true << 0.12340;
+ QTest::newRow("C: -0.12340") << u"-0.12340"_s << u"C"_s << true << -0.12340;
+ QTest::newRow("C: &minus;0.12340") << u"\u2212" "0.12340"_s << u"C"_s << true << -0.12340;
+ QTest::newRow("C: 1.0e-4") << u"1.0e-4"_s << u"C"_s << true << 1.0e-4;
+ QTest::newRow("C: 1.0e&minus;4") << u"1.0e\u2212" "4"_s << u"C"_s << true << 1.0e-4;
+ QTest::newRow("C: 1.0e+4") << u"1.0e+4"_s << u"C"_s << true << 1.0e+4;
+ QTest::newRow("C: 10.e+3") << u"10.e+3"_s << u"C"_s << true << 1.0e+4;
+ QTest::newRow("C: 10e+3.") << u"10e+3."_s << u"C"_s << false << 0.0; // exp...dot
+ QTest::newRow("C: 1e4") << u"1e4"_s << u"C"_s << true << 1.0e+4;
+
+ // NaN and infinity:
+ QTest::newRow("C: nan") << u"nan"_s << u"C"_s << true << qQNaN();
+ QTest::newRow("C: NaN") << u"NaN"_s << u"C"_s << true << qQNaN();
+ QTest::newRow("C: -nan") << u"-nan"_s << u"C"_s << false << 0.0;
+ QTest::newRow("C: +nan") << u"+nan"_s << u"C"_s << false << 0.0;
+ QTest::newRow("C: inf") << u"inf"_s << u"C"_s << true << qInf();
+ QTest::newRow("C: Inf") << u"Inf"_s << u"C"_s << true << qInf();
+ QTest::newRow("C: +inf") << u"+inf"_s << u"C"_s << true << qInf();
+ QTest::newRow("C: -inf") << u"-inf"_s << u"C"_s << true << -qInf();
+
+ // Wantonly long-form representations, with trailing and leading zeros:
+ QTest::newRow("C: 1e-64 long-form")
+ << (u"0."_s + QString(63, u'0') + u'1' + QString(962, u'0')) << u"C"_s << true << 1e-64;
+ QTest::newRow("C: 1e+64 long-form")
+ << (QString(961, u'0') + u'1' + QString(64, u'0') + u".0"_s) << u"C"_s << true << 1e+64;
+ QTest::newRow("C: long-form 1 via e+64")
+ << (u"0."_s + QString(63, u'0') + u'1' + QString(962, u'0') + u"e+64"_s)
+ << u"C"_s << true << 1.0;
+ QTest::newRow("C: long-form 1 via e-64")
+ << (QString(961, u'0') + u'1' + QString(64, u'0') + u".0e-64"_s)
+ << u"C"_s << true << 1.0;
+ QTest::newRow("C: 12345678.9") << u"12345678.9"_s << u"C"_s << true << 12345678.9;
+
+ // With and without grouping, en vs de for flipped separators:
+ QTest::newRow("en: 12345678.9") << u"12345678.9"_s << u"en"_s << true << 12345678.9;
+ QTest::newRow("en: 12,345,678.9") << u"12,345,678.9"_s << u"en"_s << true << 12'345'678.9;
+ QTest::newRow("de: 12345678,9") << u"12345678,9"_s << u"de"_s << true << 12345678.9;
+ QTest::newRow("de: 12.345.678,9") << u"12.345.678,9"_s << u"de"_s << true << 12'345'678.9;
+
+ // NaN and infinity are locale-independent (for now - QTBUG-95460)
+ QTest::newRow("cy: nan") << u"nan"_s << u"cy"_s << true << qQNaN();
+ QTest::newRow("cy: NaN") << u"NaN"_s << u"cy"_s << true << qQNaN();
+ QTest::newRow("cy: -nan") << u"-nan"_s << u"cy"_s << false << 0.0;
+ QTest::newRow("cy: +nan") << u"+nan"_s << u"cy"_s << false << 0.0;
+ QTest::newRow("cy: inf") << u"inf"_s << u"cy"_s << true << qInf();
+ QTest::newRow("cy: Inf") << u"Inf"_s << u"cy"_s << true << qInf();
+ QTest::newRow("cy: +inf") << u"+inf"_s << u"cy"_s << true << qInf();
+ QTest::newRow("cy: -inf") << u"-inf"_s << u"cy"_s << true << -qInf();
+ // Samples ready for QTBUG-95460:
+ QTest::newRow("en: &infin;") << u"\u221e"_s << u"en"_s << true << qInf();
+ QTest::newRow("ga: Nuimh") << u"Nuimh"_s << u"ga"_s << true << qQNaN();
+
+ // Locales with multi-character exponents:
+ QTest::newRow("sv_SE: 4e-3") // Swedish, Sweden
+ << u"4\u00d7" "10^\u2212" "03"_s << u"sv_SE"_s << true << 4e-3;
+ QTest::newRow("sv_SE: 4x-3") // Only first character of exponent
+ << u"4\u00d7\u2212" "03"_s << u"sv_SE"_s << false << 0.0;
+ QTest::newRow("se_NO: 4e-3") // Northern Sami, Norway
+ << u"4\u00b7" "10^\u2212" "03"_s << u"se_NO"_s << true << 4e-3;
+ QTest::newRow("se_NO: 4x-3") // Only first character of exponent
+ << u"4\u00b7\u2212" "03"_s << u"se_NO"_s << false << 0.0;
+ QTest::newRow("ar_EG: 4e-3") // Arabic, Egypt
+ << u"\u0664\u0627\u0633\u061c-\u0660\u0663"_s << u"ar_EG"_s << true << 4e-3;
+ QTest::newRow("ar_EG: 4x-3") // Only first character of exponent
+ << u"\u0664\u0627\u061c-\u0660\u0663"_s << u"ar_EG"_s << false << 0.0;
+ QTest::newRow("ar_EG: 4e!3") // Only first character of sign
+ << u"\u0664\u0627\u0633\u061c\u0660\u0663"_s << u"ar_EG"_s << false << 0.0;
+ QTest::newRow("ar_EG: 4x!3") // Only first character of sign and exponent
+ << u"\u0664\u0627\u061c\u0660\u0663"_s << u"ar_EG"_s << false << 0.0;
+}
+
+void tst_QLocale::toDouble()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, locale);
+ QFETCH(bool, good);
+ QFETCH(double, expected);
+
+ const QLocale loc(locale);
+ double actual = expected;
+ bool ok = false;
+ QBENCHMARK {
+ actual = loc.toDouble(text, &ok);
+ }
+ QEXPECT_FAIL("sv_SE: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("se_NO: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("ar_EG: 4e-3", "Code wrongly assumes single character, QTBUG-107801", Abort);
+ QEXPECT_FAIL("en: &infin;", "Localized infinity support missing: QTBUG-95460", Abort);
+ QEXPECT_FAIL("ga: Nuimh", "Localized NaN support missing: QTBUG-95460", Abort);
+ QCOMPARE(ok, good);
+ QCOMPARE(actual, expected);
+}
+
QTEST_MAIN(tst_QLocale)
#include "tst_bench_qlocale.moc"