summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2024-03-25 23:46:35 -0700
committerThiago Macieira <thiago.macieira@intel.com>2024-04-12 21:41:16 -0700
commit8e5ce9cd369230256045864d6fad38dbd8bee413 (patch)
tree92d771e5fc5aefc95f145831b011445b003562cc /src/corelib
parentedc2d414562ece8b139b1cd1fcf77df245d0573f (diff)
CBOR: implement faster comparison for equality in strings
If we don't need to sort, then we can use QtPrivate::equalStrings() to get a few cycles of performance per string comparison. Change-Id: I5f663c2f9f4149af84fefffd17c03d9b52ca696e Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/serialization/qcborvalue.cpp19
-rw-r--r--src/corelib/serialization/qcborvalue_p.h6
2 files changed, 19 insertions, 6 deletions
diff --git a/src/corelib/serialization/qcborvalue.cpp b/src/corelib/serialization/qcborvalue.cpp
index ac8ba481dd..81eb13bd54 100644
--- a/src/corelib/serialization/qcborvalue.cpp
+++ b/src/corelib/serialization/qcborvalue.cpp
@@ -1156,6 +1156,12 @@ static int compareElementRecursive(const QCborContainerPrivate *c1, const Elemen
const ByteData *b1 = c1 ? c1->byteData(e1) : nullptr;
const ByteData *b2 = c2 ? c2->byteData(e2) : nullptr;
if (b1 || b2) {
+ auto compareStrings = [mode](auto s1, auto s2) {
+ if (mode == Comparison::ForEquality)
+ return QtPrivate::equalStrings(s1, s2) ? 0 : 1;
+ return QtPrivate::compareStrings(s1, s2);
+ };
+
auto len1 = b1 ? b1->len : 0;
auto len2 = b2 ? b2->len : 0;
@@ -1184,15 +1190,20 @@ static int compareElementRecursive(const QCborContainerPrivate *c1, const Elemen
// Case 1: both UTF-16, so lengths are comparable.
// (we can't use memcmp in little-endian machines)
if (len1 == len2)
- return QtPrivate::compareStrings(b1->asStringView(), b2->asStringView());
+ return compareStrings(b1->asStringView(), b2->asStringView());
return len1 < len2 ? -1 : 1;
}
if (!(e1.flags & Element::StringIsUtf16) && !(e2.flags & Element::StringIsUtf16)) {
// Cases 4, 5 and 6: neither is UTF-16, so lengths are comparable too
// (this case includes byte arrays too)
- if (len1 == len2)
+ if (len1 == len2) {
+ if (mode == Comparison::ForEquality) {
+ // GCC optimizes this to __memcmpeq(); Clang to bcmp()
+ return memcmp(b1->byte(), b2->byte(), size_t(len1)) == 0 ? 0 : 1;
+ }
return memcmp(b1->byte(), b2->byte(), size_t(len1));
+ }
return len1 < len2 ? -1 : 1;
}
@@ -1217,8 +1228,8 @@ static int compareElementRecursive(const QCborContainerPrivate *c1, const Elemen
if (len1 != len2)
return len1 < len2 ? -1 : 1;
if (e1.flags & Element::StringIsUtf16)
- return QtPrivate::compareStrings(b1->asStringView(), b2->asLatin1());
- return QtPrivate::compareStrings(b1->asLatin1(), b2->asStringView());
+ return compareStrings(b1->asStringView(), b2->asLatin1());
+ return compareStrings(b1->asLatin1(), b2->asStringView());
}
return compareElementNoData(e1, e2);
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
index ec8d559fd0..14e20618a0 100644
--- a/src/corelib/serialization/qcborvalue_p.h
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -360,9 +360,11 @@ public:
if (!b)
return s.isEmpty() ? 0 : -1;
- Q_UNUSED(mode);
- if (e.flags & QtCbor::Element::StringIsUtf16)
+ if (e.flags & QtCbor::Element::StringIsUtf16) {
+ if (mode == QtCbor::Comparison::ForEquality)
+ return QtPrivate::equalStrings(b->asStringView(), s) ? 0 : 1;
return QtPrivate::compareStrings(b->asStringView(), s);
+ }
return compareUtf8(b, s);
}