GNU bug report logs - #20154
25.0.50; json-encode-string is too slow for large strings

Previous Next

Package: emacs;

Reported by: Dmitry Gutov <dgutov <at> yandex.ru>

Date: Fri, 20 Mar 2015 14:27:01 UTC

Severity: normal

Found in version 25.0.50

Done: Dmitry Gutov <dgutov <at> yandex.ru>

Bug is archived. No further changes may be made.

Full log


Message #65 received at 20154 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dgutov <at> yandex.ru>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 20154 <at> debbugs.gnu.org
Subject: Re: bug#20154: 25.0.50; json-encode-string is too slow for
 large strings
Date: Sat, 21 Mar 2015 23:09:57 +0200
On 03/21/2015 10:07 AM, Eli Zaretskii wrote:

> Do you really need 'format' here?  Why not
>
>      (concat "\\" (char-to-string (char-after (match-beginning 0))))
>
> instead?
>
> Or even simply insert these two parts at the match point, after
> deleting the match.

Yes, thanks. It gave a small improvement, by 5ms or so. Here's the 
updated definition (by the way, `json-special-chars' is still needed, to 
convert ?\n to ?n, and so on, and the performance hit is negligible).

(defun json-encode-string-1 (string)
  "Return a JSON representation of STRING."
  (with-temp-buffer
    (insert string)
    (goto-char (point-min))
    ;; Skip over ASCIIish printable characters.
    (while (re-search-forward "\\([\"\\/\b\f\n\r\t]\\)\\|[^ -~]" nil t)
      (let ((c (char-before)))
        (delete-region (1- (point)) (point))
        (if (match-beginning 1)
            ;; Special JSON character (\n, \r, etc.).
            (insert "\\" (car (rassoc c json-special-chars)))
          ;; Fallback: UCS code point in \uNNNN form.
          (insert (format "\\u%04x" c)))))
    (concat "\"" (buffer-string) "\"")))

Futher, it seems I didn't measure its performance well enough to begin 
with. The average time out of 10 runs comes down to 85ms.

Compare it to 150ms, from this implementation:

(defun json-encode-string-2 (string)
  "Return a JSON representation of STRING."
  (concat "\""
          (replace-regexp-in-string
           "\\([\"\\/\b\f\n\r\t]\\)\\|[^ -~]"
           (lambda (s)
             (if (match-beginning 1)
                 (format "\\%c" (car (rassoc (string-to-char s)
                                             json-special-chars)))
               (format "\\u%04x" (string-to-char s))))
           string t t)
          "\""))





This bug report was last modified 10 years and 38 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.