[Top][All Lists]
[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).