... to test the impact of migrating the underlying implementation to
QAnyStringView.
As a drive-by: use [[maybe_unused]] instead of Q_UNUSED in the
benchmark for operator[].
Task-number: QTBUG-101707
Pick-to: 6.6 6.5 6.2
Change-Id: I4bae7deadbe9bbd6f267364d78e94ea4541c1339
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Helps finding it, e.g. in QtCreator, as it's now disambiguated from
tst_QImageReader, the auto-test.
As a drive-by, remove all empty functions.
Pick-to: 6.6 6.5 6.2 5.15
Task-number: QTBUG-114253
Change-Id: Icb0a3627488bbf4cb0c9d6bc9890f31a88096afd
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Make the strings in the stringlist-to-be-joined unique, which matches
actual use-cases better than joining a list of identical strings,
especially with QString's implicit sharing, if it's copies of the same
QString, it's sharing the underlying data.
Pick-to: 6.6 6.5 6.2 5.15
Task-number: QTBUG-116859
Change-Id: I1da93885e938045322ba8337df5e4e96985f892f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Now that users can pass a QStringMatcher to do the matching, change the
existing overload to not use QStringMatcher.
Thanks to Giuseppe D'Angelo for the idea of passing a QStringMatcher to
filter instead of using a magic number to decide whether to use
QStringMatcher or not.
Results of running filter() and filter_stringMatcher, times are in msecs
and this was compiled with gcc -O3:
Without With QStringMatcher
list10 0.00022 0.000089
list20 0.00040 0.00014
list30 0.00058 0.00018
list40 0.000770 0.00023
list50 0.00094 0.00027
list70 0.0012 0.00037
list80 0.0014 0.00041
list100 0.0018 0.00050
list300 0.0054 0.0014
list500 0.0091 0.0023
list700 0.012 0.0032
list900 0.016 0.0041
list10000 0.17 0.045
Drive-by change: optimize tst_QStringList::populateList().
[ChangeLog][QtCore][QStringList] Added filter(const QStringMatcher &)
overload, which may be faster for large lists and/or lists with very
long strings.
[ChangeLog][Possible Performance Changes][QtCore][QStringList] Changed
the implementation of filter(QStringView) overload to not use
QStringMatcher by default. Using QStringMatcher adds overhead, so it is
beneficial/faster when searching for a pattern in large lists and/or
lists with long strings, otherwise using plain string comparison is
faster. If using QStringMatcher makes a difference in your code, you can
use the newly added filter(QStringMatcher) overload.
Change-Id: I7bb1262706d673f0ce0d9b7699f03c995ce28677
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Slightly improves performance in the new benchmark
Change-Id: I2d71143ff7bc1f32ebb172f20be1843dec123e6c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
In order to test the impact of migration to QASV.
Task-number: QTBUG-101707
Pick-to: 6.6 6.5 6.2
Change-Id: I17f84ca98fc87d89bb4cd6ad98c8a12aecd315ee
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The density of Q_FOREACH uses in this and some other modules is still
extremely high, too high for anyone to tackle in a short amount of
time. Even if they're not concentrated in just a few TUs, we need to
make progress on a global QT_NO_FOREACH default, so grab the nettle
and stick to our strategy:
Mark the whole of Qt with QT_NO_FOREACH, to prevent new uses from
creeping in, and whitelist the affected TUs by #undef'ing
QT_NO_FOREACH locally, at the top of each file. For TUs that are part
of a larger executable, this requires these files to be compiled
separately, so add them to NO_PCH_SOURCES (which implies
NO_UNITY_BUILD_SOURCES, too).
In tst_qglobal.cpp and tst_qcollections.cpp change the comment on the
#undef QT_NO_FOREACH to indicate that these actually test the macro.
Task-number: QTBUG-115839
Change-Id: Iecc444eb7d43d7e4d037f6e155abe0e14a00a5d6
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Instead make "benchmarks" a member variable and call qDeleteAll() on it
in cleanupTestCase(). This doesn't make much difference since the
allocated resources would be freed when the whole test is destroyed
anyway, but still.
Change-Id: Iba66d32697fd3f2283185ee65a0a514176b4b258
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
The original code duplicated contained elements of a QStringList by
repeated appending it to itself, preventing the container from being
marked const.
Instead, keep a list of unique mime-types, and iterate over the list
eight times.
As a drive-by, port from QList to a C array ("never use a
dynamically-sized container for statically-sized data"), use u""_s
UDLs (since we're touching almost all lines of the function, anyway,
also in the unrelated mimeTypeForName() call).
This allows porting the Q_FOREACH loop (which anyway cannot deal with
C arrays) to a ranged for one (which can).
Pick-to: 6.6 6.5
Task-number: QTBUG-115839
Change-Id: I844ae38104bb2980ea194b85f9017a3e95791ea2
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
These are all trivial: all are over (already or newly-made) const
local variables.
We don't have a mechanism to mark a subtree as Q_FOREACH-free, and
adding QT_NO_FOREACH to each executable is overkill, so we just have
to hope that no new uses are being introduced until we can mark the
whole QtBase module as Q_FOREACH-free.
Pick-to: 6.6 6.5
Task-number: QTBUG-115803
Change-Id: I13dc176756633674bab8c93a342ecdba6c5dd23e
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
operator=(~) and assign(~) share similar names but, until now, have not
shared the same functionality. This patch introduces the usage of
QByteArray::assign() within the non-sharing assignment operator to
effectively boost efficiency by reusing the available capacity.
Since these assignment operators are frequently used in many places,
both within Qt and non-Qt code, this patch comes with benchmarks.
The preview of the benchmark results are compared with this patch and
before this patch. The findings indicate a slight enhancement in
performance associated with the assignment operator. Despite the results
displaying only a minor improvement, progress has been made. Therefore
use assign(QByteArrayView) as replacement.
(x86_64-little_endian-lp64 shared (dynamic) release build (O3); by
gcc 13.2.1, endeavouros ; 13th Gen Intel(R) Core(TM) i9-13900K
benchmarks executed with -perf -iterations 1000000
* The last value at the EOL represent the string size.
QByteArray &operator=(const char *ch) (current)
65 cycles/iter; 317 instructions/iter; 16.0 nsec/iter (5)
71.7 cycles/iter; 383 instructions/iter; 13.0 nsec/iter (10)
59.8 cycles/iter; 318 instructions/iter; 10.9 nsec/iter (20)
70.8 cycles/iter; 340 instructions/iter; 12.9 nsec/iter (50)
80.2 cycles/iter; 419 instructions/iter; 14.6 nsec/iter (100)
164.2 cycles/iter; 899 instructions/iter; 29.9 nsec/iter (500)
260.5 cycles/iter; 1522 instructions/iter; 45.6 nsec/iter (1'000)
QByteArray &operator=(const char *ch) (before)
66.8 cycles/iter; 317 instructions/iter; 16.9 nsec/iter (5)
76.5 cycles/iter; 383 instructions/iter; 13.9 nsec/iter (10)
63.7 cycles/iter; 318 instructions/iter; 11.6 nsec/iter (20)
71.6 cycles/iter; 344 instructions/iter; 13.0 nsec/iter (50)
77.5 cycles/iter; 419 instructions/iter; 14.1 nsec/iter (100)
143.4 cycles/iter; 893 instructions/iter; 26.1 nsec/iter (500)
270.8 cycles/iter; 1516 instructions/iter; 48.2 nsec/iter (1'000)
Task-number: QTBUG-106201
Change-Id: I0745c33f0f61f1d844a60960cc55f565320d5945
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Drag the QCOMPARE (which even dynamically allocated a QString
fromLatin1()) out of the QBENCHMARK loop. Testing performance of
QString::fromLatin1() and/or qCompare() is not pertinent to the task
at hand, which, ideally, doesn't involve any memory allocations, so
there's at least the chance that this skewed the result noticably.
Didn't run the benchmark as this was developed on an asan build.
Yes, this breaks comparability with the stone-age measurements
reported in comments there, so sue me.
As a drive-by, replace the fromLatin1() with a u_s UDL.
Pick-to: 6.6 6.5
Change-Id: I9b2a8b2e3596ec9b07c6b4ea369257b1a86e09db
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: David Faure <david.faure@kdab.com>
This one isn't trivial, but straight-forward: the only place the
container is modified is in fill(). Like the setOpaqueChildren()
function, this is only called from top-level test functions, and, in
particular, not from event handlers (setAttribute() sends events).
That fill() doesn't clear() the container, even though the single
UpdateWidget instance is being reused across test functions, looks
wrong, but doesn't invalidate this analysis.
Task-number: QTBUG-115803
Change-Id: I284a19da2fe476278986c61810dd334fc73034b0
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
This is more readable and at the same time helps to eradicate some
more Q_FOREACH uses for an eventual global QT_NO_FOREACH for all Qt
sources (QTBUG-115796).
Task-number: QTBUG-115803
Change-Id: I9cbe76bee8a6306fab0c0bc94cd874405ca825ba
Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Everyone must have this by now. This test was 1193 ms of CMake time.
Since this was a PUBLIC feature, I've left it around with a constant
condition.
Change-Id: Ifbf974a4d10745b099b1fffd177754538bbff245
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Looping over the entries had a typo in it and was quite unnecessary,
as it just made a fresh copy of a list we already had.
Pick-to: 6.6 6.5 6.2 5.15
Change-Id: I0f3023b06163e5854d425d816e465785cda5fc91
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
[ChangeLog][QtCore][QFuture] Added QtFuture::makeReadyVoidFuture()
and QtFuture::makeReadyValueFuture().
Basically, these methods behave like QtFuture::makeReadyFuture(), but
QtFuture::makeReadyValueFuture() does not have a "const QList<T> &"
specialization returning QFuture<T> instead of QFuture<QList<T>>,
which allows it to always behave consistently.
This patch also introduces usage of the new methods around qtbase.
Task-number: QTBUG-109677
Change-Id: I89df8b26d82c192baad69efb5df517a8b182995f
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
The benchmarks were only copied from the tests without a proper cleanup
- therefore clean them up now.
Change-Id: I0285de3fd2b67c21e732d7f3f9d1f4937965be81
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Don't benchmark the creation of the QByteArray from the internal
buffer, that's not interesting.
Call resultView() instead of result().
On the one hand, this skews comparisons with older benchmark data.
OTOH, result() used to be the fastest way to get the result out of
QCryptographicHash or QMessageAuthenticationCode, and now it's
resultView(), so in a way, it still is a fair comparison.
Pick-to: 6.5
Change-Id: I864b2f88f01e426c5d0967f57199e13dd7cb29f8
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Because we can, and because function_ref is never null.
Pick-to: 6.5
Change-Id: If71f98860d72eaa8cf8a93bb3c59a0260d3c7660
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
With the OpenSSL 3 backend, some algorithms may not be available. Skip
benchmarking them.
Pick-to: 6.5
Change-Id: I1275332993fe15c007410e25acf59f5e3ec27894
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We could add a tst_QMessageAuthenticationCode, but it would have to
duplicate a lot of the tst_QCryptographicHash machinery, so just add
it here.
Pick-to: 6.5 6.2 5.15
Change-Id: Icc60de865c72c5e423cb3be57f58297c522791f7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
As usual, assign them to a [[maybe_unused]] variable, to avoid
potential future [[nodiscard]] problems, and to indicate to
readers of the code that there's a result that's being returned,
we're just not interested in it.
Pick-to: 6.5 6.2
Change-Id: I2bd47ca98418092ca885d50a1a6417a21a612a85
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
... conveniently wrapped in a generator, to not have to keep an
algoname() function in sync with QCryptographicHash::Algorithm.
The MaxCryptoAlgorithm constant was already stale following the
addition of BLAKE2b/s algorithms in
5d69aa3ee1.
Also make the data-driven tests have an actual Algorithm column
(was: int) to minimize casting.
Pick-to: 6.5 6.2 5.15
Change-Id: I89a6098e512a72f623fd50a6f88fc351c7bb1418
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
All the other overloads are implemented using the new one.
Windows change relies on the pre-check in the code review making sure it
compiles.
[ChangeLog][QtCore][QThread] Added sleep(std::chrono::nanoseconds)
overload.
Task-number: QTBUG-110059
Change-Id: I9a4f4bf09041788ec9275093b6b8d0386521e286
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Add a helper class which makes sure that the used table does not exist
before usage (e.g. due to leftovers from previous tests) and is properly
cleaned up on exit. This also allows to remove all usages of
safeDropTable().
Change-Id: Iefeffbd10e2f2f67985183ea822d7b6dd2b80be7
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
In some locales signs and the exponent are not single character
tokens. Replace QLocaleData::numericToCLocale() with a tokenizer that
will cope with this. At the same time, cache the locale data needed in
support of that, so that we don't repeatedly recreate QString()
objects just to compare them against input tokens.
The caching class is inspired by Thiago's proposal for fixing the
performance, which also inspires the optimization of the C locale in
the tokenizer used here.
Add some testing that round-tripping numbers via strings works for the
locales with signs and exponents that use more than one character.
Task-number: QTBUG-107801
Change-Id: I9fd8409a371ed62ed969d9ebc8b09584e752f7fb
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Include the creation of the QDir inside QBENCHMARK, otherwise
the it can hit the cached code path where subsequent runs return
results much faster.
* Same for the opendir()/readdir() test: if opendir() isn't called
again, readdir() will just return null right away.
These two issues led to nonsense results like 0.00025 msecs per
iteration, doing nothing is really quick.
While at it, port the cleanup code to QDir::removeRecursively()
Pick-to: 6.5 6.4 6.2
Change-Id: Ic1bdd92d41efe1f6d0eaaa33eca066cb7d19fc93
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
As foreshadowed when QDateTime adapted to route all QTimeSpec use
through QTimeZone, this commit deprecates the old API in favor of the
newly more capable QTimeZone-based API.
Fixes: QTBUG-108199
Change-Id: I9a3f9f94d4a5d8cc229db72b3e4731a9e318a076
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This saves (mostly in corelib/time/) some complications that used to
arise from needing different code-paths for different time-specs.
Task-number: QTBUG-108199
Change-Id: I5dbd09859fce7599f1ba761f8a0bfc4633d0bef9
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Also add optimizations for more string comparisons and add tests and
benchmarks.
[ChangeLog][QtCore][QString] Added utf-8 case-insensitive comparisons
Fixes: QTBUG-100235
Change-Id: I7c0809c6d80c00e9a5d0e8ac3ebb045cf7004a30
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
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>
Based on the tests for QString::number(), but run in reverse, with
some embelishments. Also moved some shared code from number_*_data()
to their shared number_integer_common template.
Pick-to: 6.4 6.2 5.15
Change-Id: I74e7082372166c3cdbcd6bcbc31f9003e07cbcbc
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This is a semantic patch using ClangTidyTransformator as in
qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to
handle typedefs and accesses through pointers, too:
const std::string o = "object";
auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); };
auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) {
auto exprOfDeclaredType = [&](auto decl) {
return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o);
};
return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))));
};
auto renameMethod = [&] (ArrayRef<StringRef> classes,
StringRef from, StringRef to) {
return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)),
callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))),
changeTo(cat(access(o, cat(to)), "()")),
cat("use '", to, "' instead of '", from, "'"));
};
renameMethod(<classes>, "count", "size");
renameMethod(<classes>, "length", "size");
except that the on() matcher has been replaced by one that doesn't
ignoreParens().
a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'.
Added two NOLINTNEXTLINEs in tst_qbitarray and tst_qcontiguouscache,
to avoid porting calls that explicitly test count().
Change-Id: Icfb8808c2ff4a30187e9935a51cad26987451c22
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
With -no-feature-sql, CMake would error out because the target Qt6::Sql
didn't exist. Fix this by checking if the target exists.
Task-number: QTBUG-102480
Pick-to: 6.2 6.3 6.4
Change-Id: I411631acfd336ea699833954f86711067d160c04
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
We have NTDDI_WIN10_NI (0x0A00000C) in the Win11 SDK (10.0.22621)
so bump the value in Qt (currently 0x0A00000B) to it.
And when searching for _WIN32_WINNT/WINVER/NTDDI_VERSION throughout
the whole qtbase codebase, I found some duplicated code, mostly
leftovers from the legacy time. Replace them with our own windows
header can achieve the same effect: we have defined all the necessary
macros to unblock the latest features. And place the header at the
top most place to include the macros as early as possible.
Change-Id: I37d9ac40ca9748208c7b2e89f374eda362dbefd6
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
This is a combination of Q_UNREACHABLE() with a return statement.
ATM, the return statement is unconditionally included. If we notice
that some compilers warn about return after __builtin_unreachable(),
then we can map Q_UNREACHABLE_RETURN(...) to Q_UNREACHABLE() without
having to touch all the code that uses explicit Q_UNREACHABLE() +
return.
The fact that Boost has BOOST_UNREACHABLE_RETURN() indicates that
there are compilers that complain about a lack of return after
Q_UNREACHABLE (we know that MSVC, ICC, and GHS are among them), as
well as compilers that complained about a return being present
(Coverity). Take this opportunity to properly adapt to Coverity, by
leaving out the return statement on this compiler.
Apply the macro around the code base, using a clang-tidy transformer
rule:
const std::string unr = "unr", val = "val", ret = "ret";
auto makeUnreachableReturn = cat("Q_UNREACHABLE_RETURN(",
ifBound(val, cat(node(val)), cat("")),
")");
auto ignoringSwitchCases = [](auto stmt) {
return anyOf(stmt, switchCase(subStmt(stmt)));
};
makeRule(
stmt(ignoringSwitchCases(stmt(isExpandedFromMacro("Q_UNREACHABLE")).bind(unr)),
nextStmt(returnStmt(optionally(hasReturnValue(expr().bind(val)))).bind(ret))),
{changeTo(node(unr), cat(makeUnreachableReturn,
";")), // TODO: why is the ; lost w/o this?
changeTo(node(ret), cat(""))},
cat("use ", makeUnreachableReturn))
);
where nextStmt() is copied from some upstream clang-tidy check's
private implementation and subStmt() is a private matcher that gives
access to SwitchCase's SubStmt.
A.k.a. qt-use-unreachable-return.
There were some false positives, suppressed them with NOLINTNEXTLINE.
They're not really false positiives, it's just that Clang sees the
world in one way and if conditonal compilation (#if) differs for other
compilers, Clang doesn't know better. This is an artifact of matching
two consecutive statements.
I haven't figured out how to remove the empty line left by the
deletion of the return statement, if it, indeed, was on a separate
line, so post-processed the patch to remove all the lines matching
^\+ *$ from the diff:
git commit -am meep
git reset --hard HEAD^
git diff HEAD..HEAD@{1} | sed '/^\+ *$/d' | recountdiff - | patch -p1
[ChangeLog][QtCore][QtAssert] Added Q_UNREACHABLE_RETURN() macro.
Change-Id: I9782939f16091c964f25b7826e1c0dbd13a71305
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
We've been requiring C++17 since Qt 6.0, and our qAsConst use finally
starts to bother us (QTBUG-99313), so time to port away from it
now.
Since qAsConst has exactly the same semantics as std::as_const (down
to rvalue treatment, constexpr'ness and noexcept'ness), there's really
nothing more to it than a global search-and-replace, with manual
unstaging of the actual definition and documentation in dist/,
src/corelib/doc/ and src/corelib/global/.
Task-number: QTBUG-99313
Change-Id: I4c7114444a325ad4e62d0fcbfd347d2bbfb21541
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Pre-requisite for a fix for qHash. The Qt50String inherits from QString
and becomes ambiguous once it no longer goes through a catch-all
template function because qHash(QString, size_t) has a better match for
the second argument.
Pick-to: 6.2 6.4
Change-Id: I23c7afb1b3aa167d40dc4838e82b7763de015f6b
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>