aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2019-04-23 13:20:46 +0300
committerEli Zaretskii2019-04-23 13:20:46 +0300
commitdb2c9308492a158b9fa97aa9280a7897885f7760 (patch)
tree9033b4bb43c368f883b9004ebe764616db0c7829 /src
parentb59429a43ebe96b3882b237440ac79ad95e636c8 (diff)
downloademacs-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.c20
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)
225static Lisp_Object 226static Lisp_Object
226json_make_string (const char *data, ptrdiff_t size) 227json_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