Speed up string-lessp further
* src/fns.c (Fstring_lessp): Use the memcmp fast path for ASCII-only multibyte strings as well. Specialise loops on argument multibyteness.
This commit is contained in:
parent
b858acde25
commit
123506f9ca
1 changed files with 43 additions and 13 deletions
56
src/fns.c
56
src/fns.c
|
@ -449,25 +449,55 @@ Symbols are also allowed; their print names are used instead. */)
|
|||
CHECK_STRING (string2);
|
||||
|
||||
ptrdiff_t n = min (SCHARS (string1), SCHARS (string2));
|
||||
if (!STRING_MULTIBYTE (string1) && !STRING_MULTIBYTE (string2))
|
||||
|
||||
if ((!STRING_MULTIBYTE (string1) || SCHARS (string1) == SBYTES (string1))
|
||||
&& (!STRING_MULTIBYTE (string2) || SCHARS (string2) == SBYTES (string2)))
|
||||
{
|
||||
/* Both arguments are unibyte (hot path). */
|
||||
/* Each argument is either unibyte or all-ASCII multibyte:
|
||||
we can compare bytewise.
|
||||
(Arbitrary multibyte strings cannot be compared bytewise because
|
||||
that would give a different order for raw bytes 80..FF.) */
|
||||
int d = memcmp (SSDATA (string1), SSDATA (string2), n);
|
||||
return d < 0 || (d == 0 && n < SCHARS (string2)) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
|
||||
|
||||
while (i1 < n)
|
||||
else if (STRING_MULTIBYTE (string1) && STRING_MULTIBYTE (string2))
|
||||
{
|
||||
/* When we find a mismatch, we must compare the
|
||||
characters, not just the bytes. */
|
||||
int c1 = fetch_string_char_advance (string1, &i1, &i1_byte);
|
||||
int c2 = fetch_string_char_advance (string2, &i2, &i2_byte);
|
||||
if (c1 != c2)
|
||||
return c1 < c2 ? Qt : Qnil;
|
||||
ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
|
||||
while (i1 < n)
|
||||
{
|
||||
int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
|
||||
int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
|
||||
if (c1 != c2)
|
||||
return c1 < c2 ? Qt : Qnil;
|
||||
}
|
||||
return i1 < SCHARS (string2) ? Qt : Qnil;
|
||||
}
|
||||
else if (STRING_MULTIBYTE (string1))
|
||||
{
|
||||
/* string1 multibyte, string2 unibyte */
|
||||
ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0;
|
||||
while (i1 < n)
|
||||
{
|
||||
int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
|
||||
int c2 = SREF (string2, i2++);
|
||||
if (c1 != c2)
|
||||
return c1 < c2 ? Qt : Qnil;
|
||||
}
|
||||
return i1 < SCHARS (string2) ? Qt : Qnil;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* string1 unibyte, string2 multibyte */
|
||||
ptrdiff_t i1 = 0, i2 = 0, i2_byte = 0;
|
||||
while (i1 < n)
|
||||
{
|
||||
int c1 = SREF (string1, i1++);
|
||||
int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
|
||||
if (c1 != c2)
|
||||
return c1 < c2 ? Qt : Qnil;
|
||||
}
|
||||
return i1 < SCHARS (string2) ? Qt : Qnil;
|
||||
}
|
||||
return i1 < SCHARS (string2) ? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("string-version-lessp", Fstring_version_lessp,
|
||||
|
|
Loading…
Add table
Reference in a new issue