emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[nongnu] elpa/rainbow-delimiters 9d0683d77d 034/188: 6-15x Speed improve


From: ELPA Syncer
Subject: [nongnu] elpa/rainbow-delimiters 9d0683d77d 034/188: 6-15x Speed improvement by enhancing two key functions, see commit message for benchmarks.
Date: Sat, 1 Jan 2022 00:58:50 -0500 (EST)

branch: elpa/rainbow-delimiters
commit 9d0683d77dfa22800e22b39e4c1773823f9647f8
Author: Jeremy L. Rayman <jeremy.rayman@gmail.com>
Commit: Jeremy L. Rayman <jeremy.rayman@gmail.com>

    6-15x Speed improvement by enhancing two key functions, see commit message 
for benchmarks.
    
    Replaced parse-partial-sexp with syntax-ppss, a cached version of the same 
fn.
    Used in both rainbow-delimiters-depth and 
rainbow-delimiters-char-ineligible-p.
    
    char-ineligible-p is run on every single delim as it gets highlighted.
    depth is checked every time jit-lock fn gets called (once per pass).
    
    The mode is 6-15x faster at highlighting delims now.
    
    This first step is a naive improvement, just replacing the call
    to parse-partial-sexp with syntax-ppss; there is more to gain.
    Specifically we get a list of delim locations from syntax-ppss which
    will allow us to avoid using re-search-forward+delim-type check;
    instead we can just (goto-char) for each member of the list given to
    us by syntax-ppss.
    
    Benchmarks:
    syntax-ppss benchmarks:: 2012-04-27
    
    * rainbow-delimiters-char-ineligible-p:
    
    *** rainbow-delimiters-char-ineligible-p-old::
    ***** uses (save-excursion (beginning-of-defun) (parse-partial-sexp (point) 
loc)))
    Run on an ordinary small defun, meaning beg-of-defun+parse-partial-sexp have
    lower overhead:
    (benchmark-run 10000 (rainbow-delimiters-char-ineligible-p-old (point)))
    0.382
    0.322
    0.3241
    0.3244
    0.5235 + gc
    
    Run on a LARGE color-theme defun, which causes lag for beg-of-defun +
    parse-partial-sexp. Speed degrades badly with large fn size.
    (benchmark-run 10000 (rainbow-delimiters-char-ineligible-p-old (point)))
    13.86086
    14.709195 + gc
    15.463448
    Massive performance degradation - no wonder some people reported slowdown.
    
    *** rainbow-delimiters-char-ineligible-p:
    ***** uses (syntax-ppss loc), the cached version of parse-partial-sexp
    Run on an ordinary small defun:
    (benchmark-run 10000 (rainbow-delimiters-char-ineligible-p (point)))
    0.0287
    0.1183
    -0.708 + gc
    0.1132
    0.1172
    0.1172
    0.125999
    0.12016
    On a small defun, it's about .4s slower for 10,000 runs than the old 
version.
    However, on large defuns...
    
    Run on the same LARGE defun as the char-ineligible-p-old benchmark above:
    (benchmark-run 10000 (rainbow-delimiters-char-ineligible-p (point)))
    1.69163 + gc
    0.94135
    1.06332
    0.93187
    0.93072
    On the order of a 13x speed improvement over -old fn on large defuns.
    
    * Improvements to jit-lock fn speed from char-ineligible-p change:
    *** rainbow-delimiters-propertize-region using OLD char-ineligible-p-old:
    Run propertize-regions on the rainbow-delimiters.el file:
    (benchmark-run 10 (rainbow-delimiters-propertize-region 16800 19000))
    0.07045
    0.06604
    0.06445
    0.06915
    0.06829
    
    Run propertize-region with old char-ineligible-p on a massive color-theme 
defun:
     - from 23800, 26000 (same region size as 16800 to 19000)
    (benchmark-run 10 (rainbow-delimiters-propertize-region 23800 26000))
    3.4262
    2.7935
    4.0044
    2.8100
    3.3926
    2.8331
    3.6192
    
    *** rainbow-delimiters-propertize-region using NEW char-ineligible-p:
    Run propertize-region on the rainbow-delimiters.el file:
    (benchmark-run 10 (rainbow-delimiters-propertize-region 16800 19000))
    
    0.1075
    0.1066
    0.3578 + gc
    0.1028
    We see a slowdown from the new version in jit-lock. This is likely due to
    the region from 16800-19000 only containing small fns not affected by the
    lag introduced by larger fns.
    
    Run propertize-region on a massive color-theme defun:
     - from 23800, 26000 (same region size as 16800 to 19000)
    (benchmark-run 10 (rainbow-delimiters-propertize-region 23800 26000))
    0.1583
    0.1527
    0.1539
    0.1544
    0.1557
    Huge improvement, down from about 3 seconds to 0.15s (20x improvement).
    
    * rainbow-delimiters-depth speed increase:
    *** Old rainbow-delimiters-depth:
    ***** Uses beg-of-defun+parse-partial-sexp, returns depth
    Run on smaller defun:
    (benchmark-run 10000 (rainbow-delimiters-depth-old (point)))
    0.0608 + gc
    0.31211
    0.25139
    0.50449 + gc
    0.24204
    0.25056
    
    Run on a LARGE color-theme defun:
    11.9003
    12.5897
    15.2455 + gc
    14.8487
    14.1190
    
    *** New rainbow-delimiters-depth:
    ***** uses syntax-ppss instead of beg-of-defun+parse-partial-sexp, returns 
depth
    (benchmark-run 10000 (rainbow-delimiters-depth (point)))
    0.15836
    0.17015
    0.41939 + gc
    0.16874
    0.13655
    0.13726
    0.14030
    0.62721 + gc
    0.13498
    0.23817
    Doubled speed from old fn but slower gcs when they happen.
    
    Run on a LARGE color-theme defun:
    (benchmark-run 10000 (rainbow-delimiters-depth (point)))
    0.8147
    0.8021
    0.8139
    0.6038
    Huge improvement, down from 12-15s to 0.8s (~17.5x improvement)
    
    * Total speed improvement from depth+char-ineligible-p optimizations:
    
    Run rainbow-delimiters-propertize-region on a relatively smaller defun:
    (benchmark-run 10 (rainbow-delimiters-propertize-region 16800 19000))
    0.10449
    0.41737 + gc
    0.10436
    0.10183
    0.11046
    0.10177
    0.10482
    0.10229
    Down from 0.65 seconds to 0.1 seconds (~6x improvement).
    
    Run on a LARGE color-theme defun:
    (benchmark-run 10 (rainbow-delimiters-propertize-region 23800 26000))
    0.13815
    0.20409
    0.18792
    0.19268
    0.18909
    0.18806
    0.26894
    0.18979
    Down from ~3s to 0.2s. (15x improvement).
---
 rainbow-delimiters.el | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/rainbow-delimiters.el b/rainbow-delimiters.el
index 854c0ab195..74ddcea7ab 100644
--- a/rainbow-delimiters.el
+++ b/rainbow-delimiters.el
@@ -310,7 +310,7 @@ the other rainbow-delimiters specific syntax tables based 
on the current
 major-mode. The syntax table is constructed by the function
 'rainbow-delimiters-make-syntax-table-all-delimiters'.")
 
-;; syntax-table: used with parse-partial-sexp for determining current depth.
+;; syntax-table: used with syntax-ppss for determining current depth.
 (defun rainbow-delimiters-make-syntax-table-all-delimiters (syntax-table)
   "Inherit SYNTAX-TABLE and add delimiters intended to be highlighted by mode."
   (let ((table (copy-syntax-table syntax-table)))
@@ -322,16 +322,14 @@ major-mode. The syntax table is constructed by the 
function
     (modify-syntax-entry ?\} "){" table)
     table))
 
-(defun rainbow-delimiters-depth (point)
-  "Return # of nested levels of parens, brackets, braces POINT is inside of."
-  (save-excursion
-      (beginning-of-defun)
-      (let ((depth
-             (with-syntax-table rainbow-delimiters-all-delimiters-syntax-table
-               (car (parse-partial-sexp (point) point)))))
-        (if (>= depth 0)
-            depth
-          0)))) ; ignore negative depths created by unmatched closing parens.
+(defun rainbow-delimiters-depth (loc)
+  "Return # of nested levels of parens, brackets, braces LOC is inside of."
+  (let ((depth
+         (with-syntax-table rainbow-delimiters-all-delimiters-syntax-table
+           (car (syntax-ppss loc)))))
+    (if (>= depth 0)
+        depth
+      0))) ; ignore negative depths created by unmatched closing parens.
 
 
 ;;; Text properties
@@ -404,10 +402,7 @@ Returns t if char at loc meets one of the following 
conditions:
 - Inside a string.
 - Inside a comment.
 - Is an escaped char, e.g. ?\)"
-  (let ((parse-state (save-excursion
-                       (beginning-of-defun)
-                       ;; (point) is at beg-of-defun; loc is the char location
-                       (parse-partial-sexp (point) loc))))
+  (let ((parse-state (syntax-ppss loc)))
     (or
      (nth 3 parse-state)                ; inside string?
      (nth 4 parse-state)                ; inside comment?



reply via email to

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