From: Alan Mackenzie <acm@muc.de>
To: Kan-Ru Chen <kanru@kanru.info>
Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org
Subject: Re: Slow fontification in C mode buffers
Date: Fri, 13 Jan 2012 19:12:18 +0000 [thread overview]
Message-ID: <20120113191218.GB5792@acm.acm> (raw)
In-Reply-To: <87pqfngp3r.fsf@isil.kanru.info>
Hello, Kanru.
On Sun, Dec 18, 2011 at 12:06:00AM +0800, Kan-Ru Chen wrote:
> Alan Mackenzie <acm@muc.de> 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).
next prev parent reply other threads:[~2012-01-13 19:12 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-03 13:19 Slow fontification in C mode buffers Eli Zaretskii
2011-12-03 15:03 ` Sujith
2011-12-03 15:14 ` Eli Zaretskii
2011-12-03 15:32 ` Sujith
2011-12-03 15:18 ` Alan Mackenzie
2011-12-03 16:19 ` Eli Zaretskii
2011-12-13 15:31 ` Kan-Ru Chen
2011-12-14 11:19 ` Alan Mackenzie
2011-12-14 11:30 ` Alan Mackenzie
2011-12-14 12:23 ` Alan Mackenzie
2011-12-14 13:14 ` Alan Mackenzie
2011-12-14 15:02 ` Kan-Ru Chen
2011-12-15 13:43 ` Alan Mackenzie
2011-12-15 16:16 ` Kan-Ru Chen
2011-12-15 18:12 ` Alan Mackenzie
2011-12-16 2:32 ` Kan-Ru Chen
2011-12-16 11:26 ` Alan Mackenzie
2011-12-17 16:06 ` Kan-Ru Chen
2011-12-21 10:56 ` Alan Mackenzie
2011-12-21 13:33 ` Geoff Gole
2011-12-21 16:04 ` Alan Mackenzie
2011-12-21 16:48 ` Geoff Gole
2011-12-21 18:06 ` Alan Mackenzie
2011-12-21 18:16 ` Eli Zaretskii
2011-12-21 18:32 ` Geoff Gole
2011-12-21 19:35 ` Eli Zaretskii
2011-12-23 1:56 ` Kentaro NAKAZAWA
2011-12-23 12:03 ` Alan Mackenzie
2012-01-06 22:08 ` Alan Mackenzie
2012-01-07 0:09 ` Kentaro NAKAZAWA
2012-01-07 13:50 ` Alan Mackenzie
2012-01-08 1:26 ` Kentaro NAKAZAWA
2012-01-08 10:05 ` Alan Mackenzie
2012-01-20 17:26 ` Alan Mackenzie
2012-02-06 16:14 ` Kentaro NAKAZAWA
2011-12-22 16:06 ` Kan-Ru Chen
2012-01-13 19:12 ` Alan Mackenzie [this message]
2012-01-14 9:12 ` Kan-Ru Chen
2012-01-15 21:12 ` Alan Mackenzie
2012-01-22 4:20 ` Kan-Ru Chen
2011-12-03 21:15 ` Alan Mackenzie
2011-12-04 6:00 ` Eli Zaretskii
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120113191218.GB5792@acm.acm \
--to=acm@muc.de \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=kanru@kanru.info \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).