emacs-devel
[Top][All Lists]
Advanced

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

Re: Slow fontification in C mode buffers


From: Alan Mackenzie
Subject: Re: Slow fontification in C mode buffers
Date: Fri, 13 Jan 2012 19:12:18 +0000
User-agent: Mutt/1.5.21 (2010-09-15)

Hello, Kanru.

On Sun, Dec 18, 2011 at 12:06:00AM +0800, Kan-Ru Chen wrote:
> Alan Mackenzie <address@hidden> writes:

> Please forgive me for using the other files, it is closer to the real
> case. You can get the file from

> https://hg.mozilla.org/mozilla-central/raw-file/tip/dom/base/nsDOMClassInfo.cpp

That's some file.  ;-)

> (i) Loaded elp and instrumented the c- package.
> (ii) Loaded nsDOMClassInfo.cpp
> (iii) Done M-x c++-mode
> (iv) Done M-x elp-results (to clear the accumulated times)
> (v) C-s battery until failing to find 
> (vi) M-x elp-results.

> Before:

> c-beginning-of-decl-1                          201         13.065947999  
> 0.0650047164
> c-beginning-of-statement-1                     229         13.061191     
> 0.0570357685
> c-crosses-statement-barrier-p                  35466       11.622212999  
> 0.0003277001
> c-font-lock-declarations                       16          9.4090929999  
> 0.5880683124
> c-find-decl-spots                              16          9.4089879999  
> 0.5880617499

> c-at-macro-vsemi-p                             46569       6.6139159999  
> 0.0001420240
> c-in-literal                                   46569       5.4569670000  
> 0.0001171802
> c-literal-limits                               51666       3.1393819999  
> 6.076...e-05
> c-backward-sws                                 176682      1.6644079999  
> 9.420...e-06
> c-beginning-of-macro                           104078      0.5568430000  
> 5.350...e-06

> c-state-safe-place                             72459       0.3154430000  
> 4.353...e-06
> c-parse-state                                  225         0.1421229999  
> 0.0006316577
> c-parse-state-1                                225         0.1385559999  
> 0.0006158044
> c-font-lock-enclosing-decls                    16          0.1365140000  
> 0.0085321250
> c-append-to-state-cache                        196         0.0641449999  
> 0.0003272704

> After:

> c-beginning-of-decl-1                          137         9.6732900000  
> 0.0706079562
> c-beginning-of-statement-1                     165         9.6693369999  
> 0.0586020424
> c-crosses-statement-barrier-p                  25584       8.5505400000  
> 0.0003342143
> c-font-lock-declarations                       16          6.059768      
> 0.3787355
> c-find-decl-spots                              16          6.059666      
> 0.378729125

> c-at-macro-vsemi-p                             35149       4.7420429999  
> 0.0001349126
> c-in-literal                                   35149       4.0154739999  
> 0.0001142414
> c-literal-limits                               38962       2.5425719999  
> 6.525...e-05
> c-backward-sws                                 128214      1.1421259999  
> 8.907...e-06
> c-beginning-of-macro                           78145       0.3845660000  
> 4.921...e-06

> c-state-safe-place                             54703       0.2419970000  
> 4.423...e-06
> c-parse-state                                  317         0.1464209999  
> 0.0004618958
> c-font-lock-enclosing-decls                    16          0.137945      
> 0.0086215625
> c-parse-state-1                                317         0.1331939999  
> 0.0004201703
> c-font-lock-declarators                        24          0.065522      
> 0.0027300833

I've inserted some code which checks for macro invocation by looking for
an identifier followed by '('.  More or less.

Would you please try out the following patch.  It improves things
considerably, although it might not be quite the version which gets
committed.



*** orig/cc-engine.el   2011-12-15 09:06:28.000000000 +0000
--- cc-engine.el        2011-12-15 13:41:25.000000000 +0000
***************
*** 8073,8078 ****
--- 8073,8094 ----
            next-open-brace (c-pull-open-brace paren-state)))
      open-brace))
  
+ (defun c-cheap-inside-bracelist-p (paren-state)
+   ;; Return the position of the L-brace if point is inside a brace list
+   ;; initialization of an array, etc.  This is an approximate function,
+   ;; designed for speed over accuracy.  We simply search for "= {" (naturally
+   ;; with syntactic whitespace allowed).  PAREN-STATE is the normal thing that
+   ;; it is everywhere else.
+   (let (b-pos)
+     (save-excursion
+       (while
+         (and (setq b-pos (c-pull-open-brace paren-state))
+              (progn (goto-char b-pos)
+                     (c-backward-sws)
+                     (c-backward-token-2)
+                     (not (looking-at "=")))))
+       b-pos)))
+ 
  (defun c-inside-bracelist-p (containing-sexp paren-state)
    ;; return the buffer position of the beginning of the brace list
    ;; statement if we're inside a brace list, otherwise return nil.
*** orig/cc-fonts.el    2011-12-15 09:06:28.000000000 +0000
--- cc-fonts.el 2012-01-13 18:50:02.000000000 +0000
***************
*** 407,416 ****
              ;; `parse-sexp-lookup-properties' (when it exists).
              (parse-sexp-lookup-properties
               (cc-eval-when-compile
!                (boundp 'parse-sexp-lookup-properties))))
          (goto-char
           (let ((here (point)))
!            (if (eq (car (c-beginning-of-decl-1)) 'same)
                 (point)
               here)))
          ,(c-make-font-lock-search-form regexp highlights))
--- 407,417 ----
              ;; `parse-sexp-lookup-properties' (when it exists).
              (parse-sexp-lookup-properties
               (cc-eval-when-compile
!                (boundp 'parse-sexp-lookup-properties)))
!             (BOD-limit (max (point-min) (- (point) 2000))))
          (goto-char
           (let ((here (point)))
!            (if (eq (car (c-beginning-of-decl-1 BOD-limit)) 'same)
                 (point)
               here)))
          ,(c-make-font-lock-search-form regexp highlights))
***************
*** 1317,1323 ****
              (or (looking-at c-typedef-key)
                  (goto-char start-pos)))
  
-           ;; Now analyze the construct.
            ;; In QT, "more" is an irritating keyword that expands to nothing.
            ;; We skip over it to prevent recognition of "more slots: <symbol>"
            ;; as a bitfield declaration.
--- 1318,1323 ----
***************
*** 1326,1331 ****
--- 1326,1333 ----
                        (concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)")))
              (goto-char (match-end 1))
              (c-forward-syntactic-ws))
+ 
+           ;; Now analyze the construct.
            (setq decl-or-cast (c-forward-decl-or-cast-1
                                match-pos context last-cast-end))
  
***************
*** 1394,1399 ****
--- 1396,1428 ----
              (c-fontify-recorded-types-and-refs)
              nil)
  
+            ;; Restore point, since at this point in the code it has been
+            ;; left undefined by c-forward-decl-or-cast-1 above.
+            ((progn (goto-char start-pos) nil))
+ 
+            ;; If point is inside a bracelist, there's no point checking it
+            ;; being at a declarator.
+            ((let ((paren-state (c-parse-state)))
+               (c-cheap-inside-bracelist-p paren-state))
+             nil)
+ 
+            ;; If point is just after a ")" which is followed by an
+            ;; identifier which isn't a label, or at the matching "(", we're
+            ;; at either a macro invocation, a cast, or a
+            ;; for/while/etc. statement.  The cast case is handled above.
+            ;; None of these cases can contain a declarator.
+            ((or (and (eq (char-before match-pos) ?\))
+                      (c-on-identifier)
+                      (save-excursion (not (c-forward-label))))
+                 (and (eq (char-after) ?\()
+                      (save-excursion
+                        (and
+                         (progn (c-backward-token-2) (c-on-identifier))
+                         (save-excursion (not (c-forward-label)))
+                         (progn (c-backward-token-2)
+                                (eq (char-after) ?\())))))
+             nil)
+ 
             (t
              ;; Are we at a declarator?  Try to go back to the declaration
              ;; to check this.  If we get there, check whether a "typedef"
***************
*** 1403,1408 ****
--- 1432,1440 ----
                    c-recognize-knr-p) ; Strictly speaking, bogus, but it
                                       ; speeds up lisp.h tremendously.
                (save-excursion
+                 (unless (or (eobp)
+                             (looking-at "\\s(\\|\\s)"))
+                   (forward-char))
                  (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim)))
                  (if (and (eq bod-res 'same)
                           (progn

> -- 
> Kanru

-- 
Alan Mackenzie (Nuremberg, Germany).



reply via email to

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