diff options
| author | Mattias EngdegÄrd | 2020-04-03 16:01:01 +0200 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2020-04-05 15:37:55 +0200 |
| commit | 4ed39549e3f9dbfeb2aea0e2674a7701dbc0e5ea (patch) | |
| tree | 192e8b852c9af4e70ee3ec7a7ca26ae82c57bb2c /src/coding.c | |
| parent | c7ac76603f291d432586abd2eeb75e1ca6e54863 (diff) | |
| download | emacs-4ed39549e3f9dbfeb2aea0e2674a7701dbc0e5ea.tar.gz emacs-4ed39549e3f9dbfeb2aea0e2674a7701dbc0e5ea.zip | |
Avoid expensive recoding for ASCII identity cases (bug#40407)
Optimise for the common case of encoding or decoding an ASCII-only
string using an ASCII-compatible coding, for file names in particular.
* src/coding.c (string_ascii_p): New function.
(code_convert_string): Return the input string for ASCII-only inputs
and ASCII-compatible codings.
* test/src/coding-tests.el (coding-nocopy-ascii): New test.
Diffstat (limited to 'src/coding.c')
| -rw-r--r-- | src/coding.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/coding.c b/src/coding.c index 1049f1b755a..97a6eb949a8 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -9471,6 +9471,17 @@ not fully specified.) */) | |||
| 9471 | return code_convert_region (start, end, coding_system, destination, 1, 0); | 9471 | return code_convert_region (start, end, coding_system, destination, 1, 0); |
| 9472 | } | 9472 | } |
| 9473 | 9473 | ||
| 9474 | /* Whether a string only contains chars in the 0..127 range. */ | ||
| 9475 | static bool | ||
| 9476 | string_ascii_p (Lisp_Object str) | ||
| 9477 | { | ||
| 9478 | ptrdiff_t nbytes = SBYTES (str); | ||
| 9479 | for (ptrdiff_t i = 0; i < nbytes; i++) | ||
| 9480 | if (SREF (str, i) > 127) | ||
| 9481 | return false; | ||
| 9482 | return true; | ||
| 9483 | } | ||
| 9484 | |||
| 9474 | Lisp_Object | 9485 | Lisp_Object |
| 9475 | code_convert_string (Lisp_Object string, Lisp_Object coding_system, | 9486 | code_convert_string (Lisp_Object string, Lisp_Object coding_system, |
| 9476 | Lisp_Object dst_object, bool encodep, bool nocopy, | 9487 | Lisp_Object dst_object, bool encodep, bool nocopy, |
| @@ -9502,7 +9513,21 @@ code_convert_string (Lisp_Object string, Lisp_Object coding_system, | |||
| 9502 | chars = SCHARS (string); | 9513 | chars = SCHARS (string); |
| 9503 | bytes = SBYTES (string); | 9514 | bytes = SBYTES (string); |
| 9504 | 9515 | ||
| 9505 | if (BUFFERP (dst_object)) | 9516 | if (EQ (dst_object, Qt)) |
| 9517 | { | ||
| 9518 | /* Fast path for ASCII-only input and an ASCII-compatible coding: | ||
| 9519 | act as identity. */ | ||
| 9520 | Lisp_Object attrs = CODING_ID_ATTRS (coding.id); | ||
| 9521 | if (! NILP (CODING_ATTR_ASCII_COMPAT (attrs)) | ||
| 9522 | && (STRING_MULTIBYTE (string) | ||
| 9523 | ? (chars == bytes) : string_ascii_p (string))) | ||
| 9524 | return (nocopy | ||
| 9525 | ? string | ||
| 9526 | : (encodep | ||
| 9527 | ? make_unibyte_string (SDATA (string), bytes) | ||
| 9528 | : make_multibyte_string (SDATA (string), bytes, bytes))); | ||
| 9529 | } | ||
| 9530 | else if (BUFFERP (dst_object)) | ||
| 9506 | { | 9531 | { |
| 9507 | struct buffer *buf = XBUFFER (dst_object); | 9532 | struct buffer *buf = XBUFFER (dst_object); |
| 9508 | ptrdiff_t buf_pt = BUF_PT (buf); | 9533 | ptrdiff_t buf_pt = BUF_PT (buf); |