diff options
| author | Paul Eggert | 2020-01-17 23:59:51 -0800 |
|---|---|---|
| committer | Paul Eggert | 2020-01-18 00:02:12 -0800 |
| commit | c1b6d5c5b9f8eee8aa3a8071292e8b3281ecf28a (patch) | |
| tree | f484fd77b1eec8659d17531c39e1bff1301c5b33 /src/data.c | |
| parent | bce3d89a6042da8830199d912c3b26aefaf7288c (diff) | |
| download | emacs-c1b6d5c5b9f8eee8aa3a8071292e8b3281ecf28a.tar.gz emacs-c1b6d5c5b9f8eee8aa3a8071292e8b3281ecf28a.zip | |
Improve performance when a string's byte count changes
* src/alloc.c (allocate_string_data): Now static.
Remove code for when Faset calls this function when S
already has data assigned, as that can no longer happen.
(resize_string_data): New function, which avoids relocation in
more cases than the old code did, by not bothering to relocate
when the size changes falls within the alignment slop.
* src/data.c (Faset): Use resize_string_data.
Change a while to a do-while since it must iterate at least once.
Diffstat (limited to 'src/data.c')
| -rw-r--r-- | src/data.c | 36 |
1 files changed, 10 insertions, 26 deletions
diff --git a/src/data.c b/src/data.c index c8445e7d874..cd7db6a0bb9 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2303,34 +2303,18 @@ bool-vector. IDX starts at 0. */) | |||
| 2303 | 2303 | ||
| 2304 | if (STRING_MULTIBYTE (array)) | 2304 | if (STRING_MULTIBYTE (array)) |
| 2305 | { | 2305 | { |
| 2306 | ptrdiff_t idxval_byte, nbytes; | 2306 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf; |
| 2307 | int prev_bytes, new_bytes; | 2307 | ptrdiff_t idxval_byte = string_char_to_byte (array, idxval); |
| 2308 | unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; | 2308 | unsigned char *p1 = SDATA (array) + idxval_byte; |
| 2309 | 2309 | ||
| 2310 | nbytes = SBYTES (array); | 2310 | int prev_bytes = BYTES_BY_CHAR_HEAD (*p1); |
| 2311 | idxval_byte = string_char_to_byte (array, idxval); | 2311 | int new_bytes = CHAR_STRING (c, p0); |
| 2312 | p1 = SDATA (array) + idxval_byte; | ||
| 2313 | prev_bytes = BYTES_BY_CHAR_HEAD (*p1); | ||
| 2314 | new_bytes = CHAR_STRING (c, p0); | ||
| 2315 | if (prev_bytes != new_bytes) | 2312 | if (prev_bytes != new_bytes) |
| 2316 | { | 2313 | p1 = resize_string_data (array, idxval_byte, prev_bytes, new_bytes); |
| 2317 | /* We must relocate the string data. */ | 2314 | |
| 2318 | ptrdiff_t nchars = SCHARS (array); | 2315 | do |
| 2319 | USE_SAFE_ALLOCA; | ||
| 2320 | unsigned char *str = SAFE_ALLOCA (nbytes); | ||
| 2321 | |||
| 2322 | memcpy (str, SDATA (array), nbytes); | ||
| 2323 | allocate_string_data (XSTRING (array), nchars, | ||
| 2324 | nbytes + new_bytes - prev_bytes, false); | ||
| 2325 | memcpy (SDATA (array), str, idxval_byte); | ||
| 2326 | p1 = SDATA (array) + idxval_byte; | ||
| 2327 | memcpy (p1 + new_bytes, str + idxval_byte + prev_bytes, | ||
| 2328 | nbytes - (idxval_byte + prev_bytes)); | ||
| 2329 | SAFE_FREE (); | ||
| 2330 | clear_string_char_byte_cache (); | ||
| 2331 | } | ||
| 2332 | while (new_bytes--) | ||
| 2333 | *p1++ = *p0++; | 2316 | *p1++ = *p0++; |
| 2317 | while (--new_bytes != 0); | ||
| 2334 | } | 2318 | } |
| 2335 | else | 2319 | else |
| 2336 | { | 2320 | { |