aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMattias EngdegÄrd2022-09-30 13:59:45 +0200
committerMattias EngdegÄrd2022-09-30 16:24:44 +0200
commit123506f9ca33bbca57baeac74ebe7aaf462eddc5 (patch)
tree128fd654d3ed09282c5d5b791ae48888f31f607f /src
parentb858acde25160631ce7e0e13adc579ca1a4135fb (diff)
downloademacs-123506f9ca33bbca57baeac74ebe7aaf462eddc5.tar.gz
emacs-123506f9ca33bbca57baeac74ebe7aaf462eddc5.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/src/fns.c b/src/fns.c
index 3e5a83d03d2..22e66d3653d 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -449,25 +449,55 @@ Symbols are also allowed; their print names are used instead. */)
449 CHECK_STRING (string2); 449 CHECK_STRING (string2);
450 450
451 ptrdiff_t n = min (SCHARS (string1), SCHARS (string2)); 451 ptrdiff_t n = min (SCHARS (string1), SCHARS (string2));
452 if (!STRING_MULTIBYTE (string1) && !STRING_MULTIBYTE (string2)) 452
453 if ((!STRING_MULTIBYTE (string1) || SCHARS (string1) == SBYTES (string1))
454 && (!STRING_MULTIBYTE (string2) || SCHARS (string2) == SBYTES (string2)))
453 { 455 {
454 /* Both arguments are unibyte (hot path). */ 456 /* Each argument is either unibyte or all-ASCII multibyte:
457 we can compare bytewise.
458 (Arbitrary multibyte strings cannot be compared bytewise because
459 that would give a different order for raw bytes 80..FF.) */
455 int d = memcmp (SSDATA (string1), SSDATA (string2), n); 460 int d = memcmp (SSDATA (string1), SSDATA (string2), n);
456 return d < 0 || (d == 0 && n < SCHARS (string2)) ? Qt : Qnil; 461 return d < 0 || (d == 0 && n < SCHARS (string2)) ? Qt : Qnil;
457 } 462 }
458 463 else if (STRING_MULTIBYTE (string1) && STRING_MULTIBYTE (string2))
459 ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
460
461 while (i1 < n)
462 { 464 {
463 /* When we find a mismatch, we must compare the 465 ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0, i2_byte = 0;
464 characters, not just the bytes. */ 466 while (i1 < n)
465 int c1 = fetch_string_char_advance (string1, &i1, &i1_byte); 467 {
466 int c2 = fetch_string_char_advance (string2, &i2, &i2_byte); 468 int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
467 if (c1 != c2) 469 int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
468 return c1 < c2 ? Qt : Qnil; 470 if (c1 != c2)
471 return c1 < c2 ? Qt : Qnil;
472 }
473 return i1 < SCHARS (string2) ? Qt : Qnil;
474 }
475 else if (STRING_MULTIBYTE (string1))
476 {
477 /* string1 multibyte, string2 unibyte */
478 ptrdiff_t i1 = 0, i1_byte = 0, i2 = 0;
479 while (i1 < n)
480 {
481 int c1 = fetch_string_char_advance_no_check (string1, &i1, &i1_byte);
482 int c2 = SREF (string2, i2++);
483 if (c1 != c2)
484 return c1 < c2 ? Qt : Qnil;
485 }
486 return i1 < SCHARS (string2) ? Qt : Qnil;
487 }
488 else
489 {
490 /* string1 unibyte, string2 multibyte */
491 ptrdiff_t i1 = 0, i2 = 0, i2_byte = 0;
492 while (i1 < n)
493 {
494 int c1 = SREF (string1, i1++);
495 int c2 = fetch_string_char_advance_no_check (string2, &i2, &i2_byte);
496 if (c1 != c2)
497 return c1 < c2 ? Qt : Qnil;
498 }
499 return i1 < SCHARS (string2) ? Qt : Qnil;
469 } 500 }
470 return i1 < SCHARS (string2) ? Qt : Qnil;
471} 501}
472 502
473DEFUN ("string-version-lessp", Fstring_version_lessp, 503DEFUN ("string-version-lessp", Fstring_version_lessp,