Author: rfm
Date: Wed May 27 07:18:47 2015
New Revision: 38573
URL: http://svn.gna.org/viewcvs/gnustep?rev=38573&view=rev
Log:
optimise search for a range for the case of a single character.
Modified:
libs/base/trunk/Source/NSString.m
Modified: libs/base/trunk/Source/NSString.m
URL:
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/NSString.m?rev=38573&r1=38572&r2=38573&view=diff
==============================================================================
--- libs/base/trunk/Source/NSString.m (original)
+++ libs/base/trunk/Source/NSString.m Wed May 27 07:18:47 2015
@@ -2311,6 +2311,9 @@
}
countOther = [aString length];
+
+ /* A zero length string is always found at the start of the given range.
+ */
if (0 == countOther)
{
if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
@@ -2319,6 +2322,91 @@
}
searchRange.length = 0;
return searchRange;
+ }
+
+ /* If the string to search for is a single codepoint which is not
+ * decomposable to a sequence, then it can only match the identical
+ * codepoint, so we can perform the much cheaper literal search.
+ */
+ if (1 == countOther)
+ {
+ unichar u = [aString characterAtIndex: 0];
+
+ if ((mask & NSLiteralSearch) == NSLiteralSearch || uni_is_decomp(u))
+ {
+ NSRange result;
+
+ if (searchRange.length < countOther)
+ {
+ /* Range to search is smaller than string to look for.
+ */
+ result = NSMakeRange(NSNotFound, 0);
+ }
+ else if ((mask & NSAnchoredSearch) == NSAnchoredSearch
+ || searchRange.length == 1)
+ {
+ /* Range to search is a single character.
+ */
+ if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
+ {
+ searchRange.location = NSMaxRange(searchRange) - 1;
+ }
+ if ([self characterAtIndex: searchRange.location] == u)
+ {
+ result = searchRange;
+ }
+ else
+ {
+ result = NSMakeRange(NSNotFound, 0);
+ }
+ }
+ else
+ {
+ NSUInteger pos;
+ NSUInteger end;
+
+ /* Range to search is bigger than string to look for.
+ */
+ GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
+ unichar)
+ [self getCharacters: charsSelf range: searchRange];
+ end = searchRange.length;
+ if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
+ {
+ pos = end;
+ while (pos-- > 0)
+ {
+ if (charsSelf[pos] == u)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ pos = 0;
+ while (pos < end)
+ {
+ if (charsSelf[pos] == u)
+ {
+ break;
+ }
+ pos++;
+ }
+ }
+ GS_ENDITEMBUF2()
+
+ if (pos >= end)
+ {
+ result = NSMakeRange(NSNotFound, 0);
+ }
+ else
+ {
+ result = NSMakeRange(searchRange.location + pos, countOther);
+ }
+ }
+ return result;
+ }
}
if ((mask & NSLiteralSearch) == NSLiteralSearch)
@@ -2382,58 +2470,31 @@
GS_BEGINITEMBUF2(charsSelf, (searchRange.length*sizeof(unichar)),
unichar)
[self getCharacters: charsSelf range: searchRange];
- if (1 == countOther)
+
+ if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
{
- unichar u = charsOther[0];
-
- if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
+ while (pos-- > 0)
{
- while (pos-- > 0)
+ if (memcmp(&charsSelf[pos], charsOther,
+ countOther * sizeof(unichar)) == 0)
{
- if (charsSelf[pos] == u)
- {
- break;
- }
+ break;
}
- }
- else
- {
- while (pos < end)
- {
- if (charsSelf[pos] == u)
- {
- break;
- }
- pos++;
- }
}
}
else
{
- if ((mask & NSBackwardsSearch) == NSBackwardsSearch)
+ while (pos < end)
{
- while (pos-- > 0)
+ if (memcmp(&charsSelf[pos], charsOther,
+ countOther * sizeof(unichar)) == 0)
{
- if (memcmp(&charsSelf[pos], charsOther,
- countOther * sizeof(unichar)) == 0)
- {
- break;
- }
+ break;
}
- }
- else
- {
- while (pos < end)
- {
- if (memcmp(&charsSelf[pos], charsOther,
- countOther * sizeof(unichar)) == 0)
- {
- break;
- }
- pos++;
- }
- }
+ pos++;
+ }
}
+
if (pos >= end)
{
result = NSMakeRange(NSNotFound, 0);
_______________________________________________
Gnustep-cvs mailing list
[email protected]
https://mail.gna.org/listinfo/gnustep-cvs