diff options
| author | Eli Zaretskii | 2019-04-23 13:20:46 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2019-04-23 13:20:46 +0300 |
| commit | db2c9308492a158b9fa97aa9280a7897885f7760 (patch) | |
| tree | 9033b4bb43c368f883b9004ebe764616db0c7829 /src | |
| parent | b59429a43ebe96b3882b237440ac79ad95e636c8 (diff) | |
| download | emacs-db2c9308492a158b9fa97aa9280a7897885f7760.tar.gz emacs-db2c9308492a158b9fa97aa9280a7897885f7760.zip | |
Speed up JSON parsing
Thanks to Dmitry Gutov <dgutov@yandex.ru> for running many
benchmarks and for useful discussions.
* src/json.c (json_make_string): Speed up parsing of JSON
strings by optimizing the normal case of a valid UTF-8 string
being returned from libjansson. (Bug#31138)
Diffstat (limited to 'src')
| -rw-r--r-- | src/json.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/json.c b/src/json.c index 256d485eead..33e8125f981 100644 --- a/src/json.c +++ b/src/json.c | |||
| @@ -217,7 +217,8 @@ json_has_suffix (const char *string, const char *suffix) | |||
| 217 | 217 | ||
| 218 | /* Create a multibyte Lisp string from the UTF-8 string in | 218 | /* Create a multibyte Lisp string from the UTF-8 string in |
| 219 | [DATA, DATA + SIZE). If the range [DATA, DATA + SIZE) does not | 219 | [DATA, DATA + SIZE). If the range [DATA, DATA + SIZE) does not |
| 220 | contain a valid UTF-8 string, an unspecified string is returned. | 220 | contain a valid UTF-8 string, the returned string will include raw |
| 221 | bytes. | ||
| 221 | Note that all callers below either pass only value UTF-8 strings or | 222 | Note that all callers below either pass only value UTF-8 strings or |
| 222 | use this function for formatting error messages; in the latter case | 223 | use this function for formatting error messages; in the latter case |
| 223 | correctness isn't critical. */ | 224 | correctness isn't critical. */ |
| @@ -225,8 +226,21 @@ json_has_suffix (const char *string, const char *suffix) | |||
| 225 | static Lisp_Object | 226 | static Lisp_Object |
| 226 | json_make_string (const char *data, ptrdiff_t size) | 227 | json_make_string (const char *data, ptrdiff_t size) |
| 227 | { | 228 | { |
| 228 | return code_convert_string (make_specified_string (data, -1, size, false), | 229 | ptrdiff_t chars, bytes; |
| 229 | Qutf_8_unix, Qt, false, true, true); | 230 | parse_str_as_multibyte ((const unsigned char *) data, size, &chars, &bytes); |
| 231 | /* If DATA is a valid UTF-8 string, we can convert it to a Lisp | ||
| 232 | string directly. Otherwise, we need to decode it. */ | ||
| 233 | if (chars == size || bytes == size) | ||
| 234 | return make_specified_string (data, chars, size, true); | ||
| 235 | else | ||
| 236 | { | ||
| 237 | struct coding_system coding; | ||
| 238 | setup_coding_system (Qutf_8_unix, &coding); | ||
| 239 | coding.mode |= CODING_MODE_LAST_BLOCK; | ||
| 240 | coding.source = data; | ||
| 241 | decode_coding_object (&coding, Qnil, 0, 0, size, size, Qt); | ||
| 242 | return coding.dst_object; | ||
| 243 | } | ||
| 230 | } | 244 | } |
| 231 | 245 | ||
| 232 | /* Create a multibyte Lisp string from the NUL-terminated UTF-8 | 246 | /* Create a multibyte Lisp string from the NUL-terminated UTF-8 |