aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Oteiza2017-09-15 09:49:27 -0400
committerMark Oteiza2017-09-15 09:49:27 -0400
commit3b783a75ad6b609d4e0f60c2d31d4fe91dd08c62 (patch)
treecc68fda423370b7ff00cc6f5dd81de61b698c6e7
parent817e92b2bddbdbe18d3b8cd34533b4bec04d313d (diff)
downloademacs-3b783a75ad6b609d4e0f60c2d31d4fe91dd08c62.tar.gz
emacs-3b783a75ad6b609d4e0f60c2d31d4fe91dd08c62.zip
More JSON optimization
Last I checked, inlining json-skip-whitespace didn't make much difference. However, changing defsubsts to define-inline results in roughly 15% reduction in read time on a 200K file. * lisp/json.el (json-advance, json-peek, json-pop): (json-skip-whitespace): Inline with define-inline. (json-read-keyword): Don't use whitespace syntax. (json-add-to-object): Simpler condition.
-rw-r--r--lisp/json.el35
1 files changed, 18 insertions, 17 deletions
diff --git a/lisp/json.el b/lisp/json.el
index 7e924b67778..1e724b42e75 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -187,29 +187,30 @@ Unlike `reverse', this keeps the property-value pairs intact."
187 187
188;; Reader utilities 188;; Reader utilities
189 189
190(defsubst json-advance (&optional n) 190(define-inline json-advance (&optional n)
191 "Advance N characters forward." 191 "Advance N characters forward."
192 (forward-char n)) 192 (inline-quote (forward-char ,n)))
193 193
194(defsubst json-peek () 194(define-inline json-peek ()
195 "Return the character at point." 195 "Return the character at point."
196 (following-char)) 196 (inline-quote (following-char)))
197 197
198(defsubst json-pop () 198(define-inline json-pop ()
199 "Advance past the character at point, returning it." 199 "Advance past the character at point, returning it."
200 (let ((char (json-peek))) 200 (inline-letevals ((char (json-peek)))
201 (if (zerop char) 201 (inline-quote
202 (signal 'json-end-of-file nil) 202 (if (zerop ,char)
203 (json-advance) 203 (signal 'json-end-of-file nil)
204 char))) 204 (json-advance)
205 205 ,char))))
206(defun json-skip-whitespace () 206
207(define-inline json-skip-whitespace ()
207 "Skip past the whitespace at point." 208 "Skip past the whitespace at point."
208 ;; See 209 ;; See
209 ;; https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf 210 ;; https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
210 ;; or https://tools.ietf.org/html/rfc7159#section-2 for the 211 ;; or https://tools.ietf.org/html/rfc7159#section-2 for the
211 ;; definition of whitespace in JSON. 212 ;; definition of whitespace in JSON.
212 (skip-chars-forward "\t\r\n ")) 213 (inline-quote (skip-chars-forward "\t\r\n ")))
213 214
214 215
215 216
@@ -303,7 +304,8 @@ KEYWORD is the keyword expected."
303 (thing-at-point 'word))))) 304 (thing-at-point 'word)))))
304 (json-advance)) 305 (json-advance))
305 keyword) 306 keyword)
306 (unless (looking-at "\\(\\s-\\|[],}]\\|$\\)") 307 (json-skip-whitespace)
308 (unless (memq (following-char) '(?\] ?, ?}))
307 (signal 'json-unknown-keyword 309 (signal 'json-unknown-keyword
308 (list (save-excursion 310 (list (save-excursion
309 (backward-word-strictly 1) 311 (backward-word-strictly 1)
@@ -470,11 +472,10 @@ Returns the updated object, which you should save, e.g.:
470 (setq obj (json-add-to-object obj \"foo\" \"bar\")) 472 (setq obj (json-add-to-object obj \"foo\" \"bar\"))
471Please see the documentation of `json-object-type' and `json-key-type'." 473Please see the documentation of `json-object-type' and `json-key-type'."
472 (let ((json-key-type 474 (let ((json-key-type
473 (if (eq json-key-type nil) 475 (or json-key-type
474 (cdr (assq json-object-type '((hash-table . string) 476 (cdr (assq json-object-type '((hash-table . string)
475 (alist . symbol) 477 (alist . symbol)
476 (plist . keyword)))) 478 (plist . keyword)))))))
477 json-key-type)))
478 (setq key 479 (setq key
479 (cond ((eq json-key-type 'string) 480 (cond ((eq json-key-type 'string)
480 key) 481 key)