ICU-22286 Speed up substring equality comparison

This commit is contained in:
Ivan Tymoshenko 2023-02-19 18:11:18 +01:00 committed by Markus Scherer
parent 7ed7d42f58
commit 2c46fb7f61
2 changed files with 81 additions and 12 deletions

View file

@ -3489,6 +3489,19 @@ private:
*/
UBool doEquals(const UnicodeString &text, int32_t len) const;
inline UBool
doEqualsSubstring(int32_t start,
int32_t length,
const UnicodeString& srcText,
int32_t srcStart,
int32_t srcLength) const;
UBool doEqualsSubstring(int32_t start,
int32_t length,
const char16_t *srcChars,
int32_t srcStart,
int32_t srcLength) const;
inline int8_t
doCompare(int32_t start,
int32_t length,
@ -3946,6 +3959,21 @@ UnicodeString::doCompare(int32_t start,
}
}
inline UBool
UnicodeString::doEqualsSubstring(int32_t start,
int32_t thisLength,
const UnicodeString& srcText,
int32_t srcStart,
int32_t srcLength) const
{
if(srcText.isBogus()) {
return isBogus();
} else {
srcText.pinIndices(srcStart, srcLength);
return !isBogus() && doEqualsSubstring(start, thisLength, srcText.getArrayStart(), srcStart, srcLength);
}
}
inline bool
UnicodeString::operator== (const UnicodeString& text) const
{
@ -4326,20 +4354,20 @@ UnicodeString::lastIndexOf(UChar32 c,
inline UBool
UnicodeString::startsWith(const UnicodeString& text) const
{ return compare(0, text.length(), text, 0, text.length()) == 0; }
{ return doEqualsSubstring(0, text.length(), text, 0, text.length()); }
inline UBool
UnicodeString::startsWith(const UnicodeString& srcText,
int32_t srcStart,
int32_t srcLength) const
{ return doCompare(0, srcLength, srcText, srcStart, srcLength) == 0; }
{ return doEqualsSubstring(0, srcLength, srcText, srcStart, srcLength); }
inline UBool
UnicodeString::startsWith(ConstChar16Ptr srcChars, int32_t srcLength) const {
if(srcLength < 0) {
srcLength = u_strlen(toUCharPtr(srcChars));
}
return doCompare(0, srcLength, srcChars, 0, srcLength) == 0;
return doEqualsSubstring(0, srcLength, srcChars, 0, srcLength);
}
inline UBool
@ -4347,21 +4375,21 @@ UnicodeString::startsWith(const char16_t *srcChars, int32_t srcStart, int32_t sr
if(srcLength < 0) {
srcLength = u_strlen(toUCharPtr(srcChars));
}
return doCompare(0, srcLength, srcChars, srcStart, srcLength) == 0;
return doEqualsSubstring(0, srcLength, srcChars, srcStart, srcLength);
}
inline UBool
UnicodeString::endsWith(const UnicodeString& text) const
{ return doCompare(length() - text.length(), text.length(),
text, 0, text.length()) == 0; }
{ return doEqualsSubstring(length() - text.length(), text.length(),
text, 0, text.length()); }
inline UBool
UnicodeString::endsWith(const UnicodeString& srcText,
int32_t srcStart,
int32_t srcLength) const {
srcText.pinIndices(srcStart, srcLength);
return doCompare(length() - srcLength, srcLength,
srcText, srcStart, srcLength) == 0;
return doEqualsSubstring(length() - srcLength, srcLength,
srcText, srcStart, srcLength);
}
inline UBool
@ -4370,8 +4398,7 @@ UnicodeString::endsWith(ConstChar16Ptr srcChars,
if(srcLength < 0) {
srcLength = u_strlen(toUCharPtr(srcChars));
}
return doCompare(length() - srcLength, srcLength,
srcChars, 0, srcLength) == 0;
return doEqualsSubstring(length() - srcLength, srcLength, srcChars, 0, srcLength);
}
inline UBool
@ -4381,8 +4408,8 @@ UnicodeString::endsWith(const char16_t *srcChars,
if(srcLength < 0) {
srcLength = u_strlen(toUCharPtr(srcChars + srcStart));
}
return doCompare(length() - srcLength, srcLength,
srcChars, srcStart, srcLength) == 0;
return doEqualsSubstring(length() - srcLength, srcLength,
srcChars, srcStart, srcLength);
}
//========================================

View file

@ -662,6 +662,48 @@ UnicodeString::doEquals(const UnicodeString &text, int32_t len) const {
return uprv_memcmp(getArrayStart(), text.getArrayStart(), len * U_SIZEOF_UCHAR) == 0;
}
UBool
UnicodeString::doEqualsSubstring( int32_t start,
int32_t length,
const char16_t *srcChars,
int32_t srcStart,
int32_t srcLength) const
{
// compare illegal string values
if(isBogus()) {
return false;
}
// pin indices to legal values
pinIndices(start, length);
if(srcChars == nullptr) {
// treat const char16_t *srcChars==nullptr as an empty string
return length == 0 ? true : false;
}
// get the correct pointer
const char16_t *chars = getArrayStart();
chars += start;
srcChars += srcStart;
// get the srcLength if necessary
if(srcLength < 0) {
srcLength = u_strlen(srcChars + srcStart);
}
if (length != srcLength) {
return false;
}
if(length == 0 || chars == srcChars) {
return true;
}
return u_memcmp(chars, srcChars, srcLength) == 0;
}
int8_t
UnicodeString::doCompare( int32_t start,
int32_t length,