diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2024-03-25 23:46:35 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2024-04-12 21:41:16 -0700 |
commit | 8e5ce9cd369230256045864d6fad38dbd8bee413 (patch) | |
tree | 92d771e5fc5aefc95f145831b011445b003562cc /src/corelib | |
parent | edc2d414562ece8b139b1cd1fcf77df245d0573f (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.cpp | 19 | ||||
-rw-r--r-- | src/corelib/serialization/qcborvalue_p.h | 6 |
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); } |