bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#20154: 25.0.50; json-encode-string is too slow for large strings


From: Dmitry Gutov
Subject: bug#20154: 25.0.50; json-encode-string is too slow for large strings
Date: Sat, 21 Mar 2015 23:09:57 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:36.0) Gecko/20100101 Thunderbird/36.0

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)
          "\""))






reply via email to

[Prev in Thread] Current Thread [Next in Thread]