branch: elpa/php-mode
commit b73529f00e0931e280158d4e65dc1327e2a09789
Author: USAMI Kenta <[email protected]>
Commit: USAMI Kenta <[email protected]>

    Memoize php-buffer-has-html-tag to speed up indentation
    
    php-check-html-for-indentation calls php-buffer-has-html-tag on every
    line indentation, and the function scans the whole buffer from the start.
    For a plain PHP file with no HTML tag it always scans to the end, so on a
    large file most of the per-line indentation time is spent re-scanning.
    
    Cache the result by buffer-chars-modified-tick and recompute it only
    after the buffer text changes.  On tcpdf.php (8513 lines, 294 KB) a warm
    php-cautious-indent-line drops from about 3.85 ms to 0.26 ms, and the
    result still tracks HTML tags added or removed by later edits.
---
 lisp/php.el | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/lisp/php.el b/lisp/php.el
index 3124ced08b..d4b46994bd 100644
--- a/lisp/php.el
+++ b/lisp/php.el
@@ -632,14 +632,27 @@ Look at the `php-executable' variable instead of the 
constant \"php\" command."
       (symbol-value php-re-detect-html-tag)
     php-re-detect-html-tag))
 
+(defvar-local php--buffer-has-html-tag-cache nil
+  "Memoized result of `php-buffer-has-html-tag'.
+A cons of (CHARS-MODIFIED-TICK . RESULT) so the scan is repeated only
+after the buffer text changes.")
+
 (defun php-buffer-has-html-tag ()
-  "Return position of HTML tag or NIL in current buffer."
-  (save-excursion
-    (save-restriction
-      (widen)
-      (goto-char (point-min))
-      (save-match-data
-        (re-search-forward (php-re-detect-html-tag) nil t)))))
+  "Return position of HTML tag or NIL in current buffer.
+The result is cached per buffer and recomputed only when the buffer text
+has changed, because this scans the whole buffer and is called on every
+indentation."
+  (let ((tick (buffer-chars-modified-tick)))
+    (if (eql (car php--buffer-has-html-tag-cache) tick)
+        (cdr php--buffer-has-html-tag-cache)
+      (let ((result (save-excursion
+                      (save-restriction
+                        (widen)
+                        (goto-char (point-min))
+                        (save-match-data
+                          (re-search-forward (php-re-detect-html-tag) nil 
t))))))
+        (setq php--buffer-has-html-tag-cache (cons tick result))
+        result))))
 
 (defun php-derivation-major-mode ()
   "Return major mode for PHP file by file-name and its content."

Reply via email to