Tidy up QByteArray::toPercentEncoding()

After inlining the local static void to which it used to delegate most
of the work, the main loop can access *this and we have no need for
yet another copy of it or the variables to iterate it. We can also
access the result array directly, rather than via a (poorly-named)
pointer.

It turns out that wrapping QBA in QBAV each time we call a lambda on
it costs enough to cause a 50% slowdown, so change the lambda to now
take the const refs we have. (Constructing the views only once is as
good, for reference.)

Change-Id: I81c5996d91415d8a933de714177a89462555ff03
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Edward Welbourne 2022-03-07 17:05:24 +01:00
parent 73e7fc2d8e
commit 0cee66048d

View File

@ -4600,21 +4600,16 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
if (isEmpty())
return QByteArray(data(), 0);
const auto contains = [](QByteArrayView view, char c) {
const auto contains = [](const QByteArray &view, char c) {
// As view.contains(c), but optimised to bypass a lot of overhead:
return view.size() > 0 && memchr(view.data(), c, view.size()) != nullptr;
};
QByteArray result = *this;
QByteArray *ba = &result;
QByteArray input = *ba;
qsizetype len = input.size();
const char *inputData = input.constData();
char *output = nullptr;
qsizetype length = 0;
for (qsizetype i = 0; i < len; ++i) {
unsigned char c = *inputData++;
for (unsigned char c : *this) {
if (c != percent
&& ((c >= 0x61 && c <= 0x7A) // ALPHA
|| (c >= 0x41 && c <= 0x5A) // ALPHA
@ -4631,8 +4626,8 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
} else {
if (!output) {
// detach now
ba->resize(len*3); // worst case
output = ba->data();
result.resize(size() * 3); // worst case
output = result.data();
}
output[length++] = percent;
output[length++] = QtMiscUtils::toHexUpper((c & 0xf0) >> 4);
@ -4640,7 +4635,7 @@ QByteArray QByteArray::toPercentEncoding(const QByteArray &exclude, const QByteA
}
}
if (output)
ba->truncate(length);
result.truncate(length);
return result;
}