From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: =?UTF-8?Q?Bj=C3=B6rn?= Lindqvist Newsgroups: gmane.emacs.bugs Subject: bug#74357: c-mode: Some syntactic constructs cause unreasonable typing lag Date: Sat, 30 Nov 2024 19:04:31 +0100 Message-ID: References: <86v7wphrmi.fsf@gnu.org> <86ed3cinfg.fsf@gnu.org> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="39146"; mail-complaints-to="usenet@ciao.gmane.io" Cc: Eli Zaretskii , 74357@debbugs.gnu.org To: Alan Mackenzie Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Nov 30 19:06:34 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tHRrV-000A2U-IR for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 30 Nov 2024 19:06:33 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tHRr4-0007ar-QK; Sat, 30 Nov 2024 13:06:06 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tHRr2-0007ah-Ql for bug-gnu-emacs@gnu.org; Sat, 30 Nov 2024 13:06:04 -0500 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tHRr0-0001eP-UJ for bug-gnu-emacs@gnu.org; Sat, 30 Nov 2024 13:06:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=debbugs.gnu.org; s=debbugs-gnu-org; h=Date:From:In-Reply-To:References:MIME-Version:To:Subject; bh=zOnePDXjOcQaWQEiz2n/hiuL8th54R06Sj8XXClAWf0=; b=p+sVTvYzLg1AiMo0iUqfL2wn++Kc53ujrXWREWn/Qhilj3t8yls9kj0LA0gW9BnGj+fTOcuzwGYMMbnvSzLBnE/QRfAOHIh8pDRLN+eQdrt2y1u4qmPaFe+di7foMWqYY3fyMfc9fOk0xqeuIfuiyJ4FJAL1n9ntpu7RHv/vvDsWD0BQDc5CqeREyLYRCcd5Cv8X9FAJFbdY8SgdF3VxSBr2UD81xaWpCyCpq4euqnrsO3B6TbIRY2VO9ImMgt33BlTW925Qpt2X5inbpLTNDiizWxYchD+Jqm3lwmFh0l5s+WL2LYtoJcbpKPxPeclU03bqdaEQlOap4IbooRZqSA==; Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1tHRr0-0008En-Cu for bug-gnu-emacs@gnu.org; Sat, 30 Nov 2024 13:06:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: =?UTF-8?Q?Bj=C3=B6rn?= Lindqvist Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 30 Nov 2024 18:06:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 74357 X-GNU-PR-Package: emacs Original-Received: via spool by 74357-submit@debbugs.gnu.org id=B74357.173298995131634 (code B ref 74357); Sat, 30 Nov 2024 18:06:02 +0000 Original-Received: (at 74357) by debbugs.gnu.org; 30 Nov 2024 18:05:51 +0000 Original-Received: from localhost ([127.0.0.1]:48940 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHRqo-0008E9-QJ for submit@debbugs.gnu.org; Sat, 30 Nov 2024 13:05:51 -0500 Original-Received: from mail-qt1-f169.google.com ([209.85.160.169]:50256) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1tHRqm-0008Dn-7s for 74357@debbugs.gnu.org; Sat, 30 Nov 2024 13:05:49 -0500 Original-Received: by mail-qt1-f169.google.com with SMTP id d75a77b69052e-466929d6013so28445141cf.0 for <74357@debbugs.gnu.org>; Sat, 30 Nov 2024 10:05:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1732989882; x=1733594682; darn=debbugs.gnu.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=zOnePDXjOcQaWQEiz2n/hiuL8th54R06Sj8XXClAWf0=; b=gJWZ1+p9vuHmvVjZYeJ+896gWU89wkxXn24RBmKluWNFN6GMUu7gMKO9zVBe/xl/zE QT03f4pv4P7dYjUzlle2xmMmCIdbJ+D/w+QPxCtv3qlCas3UYnw23bj5tNvn50lfpXVB +D6/5vb4echwF7F2jhAVPAGS64AKhktC/AuI2fbi5ULsT8ctJnF/BTMfcZenbtahug4g Sdd6GMBxr3Vq/VD+B63vI69b5W4LJe+zzGCNjWZjPZecbOdv1leJrF1zb7HvdpA1icFA 3TQx43k289sbnBgQvFwle5+cn7PnBC4Bg2O/t4VOlKfKczV2ubyIEC0dL7vgClsGZ4zx 1oMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732989882; x=1733594682; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zOnePDXjOcQaWQEiz2n/hiuL8th54R06Sj8XXClAWf0=; b=Y4DaoUGoW4Z1CjFeAcgOeecCaKetMvZqO0oHMy8EPh9byngp+SmDJ0iyL/wGyu1a95 El41rTMpMvK9Xp2Yk60k0nT25pwNzRn1f75b09O7zRVCGjNQx18g5L1gLB8s10bpVlsV tZjZpTItnp4zNuUN5YYFlsMXFDHK7GuSwmNsspSfRK7y24d3XIG/e4YwdDF+Qty/QLvQ aqAVSe8h/anjOv51D8mKlJoTrs4g47vt71kHHZgOUyRnMzi1LWuHrgnkgRqCHCzo5ikm LIB+0pN25zjJjfuRhFyri759igrM+BeSD/+br8ya4VKcqNN/KgzpIU0BYBGXdtKCF4sD UDbg== X-Forwarded-Encrypted: i=1; AJvYcCVWCira8z3P41idcjdeF9lvWHk3t5h2uDOAJ7hu22t791+dFGiEUhJJoA/GSQ8M6K8v5nrPBA==@debbugs.gnu.org X-Gm-Message-State: AOJu0Yw8ENodnSfziZxCvimLKoYTDOWRf0dFRi95o7lgz/glvMV6qenL jIAyoneMYqkzFj7SeOErLsL7CM1KeISDMOIWfZO43bcmmUvZLjhcMnfGfkAy42eLqHdRC/2Pwu+ XVdGobQxzhPuPZVmAfTbQL95an3lHOpb5 X-Gm-Gg: ASbGncsfB700DFKd1CKuHVrClpRfsghyDgZlkhcWfXu19ZB2hpULR8vU59Edebazirn hjTkkYkwL/KlPzgFXQSLK5Rfcx7lxRIOY7CCiaBbSWsH1m/ejO87zrR+lXxE= X-Google-Smtp-Source: AGHT+IHGe2FAS9Wss4b7ABg/QZigEGUt8/ZgyR//NBgwlGsW5tODIrE08nFqAI20r+Wnpo6SKVjCu/LSbfYeXkj332U= X-Received: by 2002:a05:620a:4807:b0:7b6:704e:3529 with SMTP id af79cd13be357-7b67c460a14mr2279618585a.46.1732989882492; Sat, 30 Nov 2024 10:04:42 -0800 (PST) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:296187 Archived-At: Hello Alan, I applied your patch (patch < patch.diff), then I byte-compiled the changed elisp files (emacs -batch -f batch-byte-compile cc-engine.el, emacs -batch -f batch-byte-compile cc-mode.el), and then I installed them over the existing .elc files. Maybe I applied the patch wrong because it didn't improve performance. You can find a new profiler report here: https://gist.github.com/bjourne/c715e15729c841d1f68e00499c622d77 Den l=C3=B6r 30 nov. 2024 kl 00:18 skrev Alan Mackenzie : > > Hello again, Bj=C3=B6rn. > > On Thu, Nov 28, 2024 at 20:03:33 +0000, Alan Mackenzie wrote: > > On Fri, Nov 15, 2024 at 22:43:45 +0100, Bj=C3=B6rn Lindqvist wrote: > > > Den fre 15 nov. 2024 kl 15:25 skrev Eli Zaretskii : > > > > Can you tell where in real life do you see such deeply-nested brace= s > > > > in C source files? > > > > 50 is perhaps exaggerating it, but in "modern" C++ with multiple > > > namespaces, nested classes, and anonymous functions you can easily ge= t > > > scopes nested over a dozen levels deep. > > > In your test file, near the end, holding down the 'y' key as you > > describe, most of the time CC Mode is scanning for brace lists (and not > > finding them). ("Brace lists" are things like the initialisation forms > > for structs and arrays, not statement blocks.) > > > There is a cache mechanism to help reduce this scanning, but with the > > deep nesting in the test file, it seems to be ineffective, with element= s > > of that cache continually being overwritten by new elements. The cache > > currently has just four elements. Maybe it would be better to increase > > that number. Maybe there's some other problem with the cache. I'm > > looking into it. > > It turns out that that cache mechanism was almost totally ineffective. > I've put a new cache into c-inside-bracelist-p. More precisely, I've > reused an existing cache in a new way. > > Would you please apply the patch below to your CC Mode, byte compile CC > Mode, and test it a bit to see if it's fast enough. (If you want any > help applying the patch or byte compiling the result, feel free to send > me private email.) > > Thanks! > > > diff -r 2c1ba136f3f2 cc-engine.el > --- a/cc-engine.el Mon Oct 28 15:47:50 2024 +0000 > +++ b/cc-engine.el Fri Nov 29 23:12:27 2024 +0000 > @@ -13178,7 +13178,7 @@ > (setq c-laomib-cache (delq elt c-laomib-cache))))))) > > (defun c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim= ) > - ;; Point is at an open brace. If this starts a brace list, return a l= ist > + ;; Point is at an open brace. If this starts a brace list, return a c= ons > ;; whose car is the buffer position of the start of the construct whic= h > ;; introduces the list, and whose cdr is the symbol `in-paren' if the = brace > ;; is directly enclosed in a parenthesis form (i.e. an arglist), t if = we > @@ -13411,14 +13411,19 @@ > (t t)))) ;; The caller can go up one level= . > )))) > > +;; A list of the form returned by `c-parse-state'. Each opening brace i= n it > +;; is not the brace of a brace list. > +(defvar c-no-bracelist-cache nil) > +(make-variable-buffer-local 'c-no-bracelist-cache) > + > (defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren= ) > - ;; return the buffer position of the beginning of the brace list state= ment > + ;; Return the buffer position of the beginning of the brace list state= ment > ;; if CONTAINING-SEXP is inside a brace list, otherwise return nil. > ;; > - ;; CONTAINING-SEXP is the buffer pos of the innermost containing paren= . NO > - ;; IT ISN'T!!! [This function is badly designed, and probably needs > - ;; reformulating without its first argument, and the critical position= being > - ;; at point.] > + ;; CONTAINING-SEXP must be at an open brace, and is the buffer pos of = the > + ;; innermost containing brace. NO IT ISN'T!!! [This function is badl= y > + ;; designed, and probably needs reformulating without its first argume= nt, > + ;; and the critical position being at point.] > ;; > ;; PAREN-STATE is the remainder of the state of enclosing braces. > ;; ACCEPT-IN-PAREN is non-nil iff we will accept as a brace list a bra= ce > @@ -13432,32 +13437,42 @@ > ;; speed. > ;; > ;; This function might do hidden buffer changes. > - ;; this will pick up array/aggregate init lists, even if they are nest= ed. > - (save-excursion > - (let ((bufpos t) > - next-containing) > - (while (and (eq bufpos t) > - containing-sexp) > - (when paren-state > - (setq next-containing (c-pull-open-brace paren-state))) > - > - (goto-char containing-sexp) > - (if (c-looking-at-inexpr-block next-containing next-containing) > - ;; We're in an in-expression block of some kind. Do not > - ;; check nesting. We deliberately set the limit to the > - ;; containing sexp, so that c-looking-at-inexpr-block > - ;; doesn't check for an identifier before it. > - (setq bufpos nil) > - (if (not (eq (char-after) ?{)) > - (setq bufpos nil) > - (when (eq (setq bufpos (c-looking-at-or-maybe-in-bracelist > - next-containing next-containing= )) > - t) > - (setq containing-sexp next-containing > - next-containing nil))))) > - (and (consp bufpos) > - (or accept-in-paren (not (eq (cdr bufpos) 'in-paren))) > - (car bufpos))))) > + ;; It will pick up array/aggregate init lists, even if they are nested= . > + (save-excursion > + (let ((bufpos t) > + next-containing > + (whole-paren-state (cons containing-sexp paren-state)) > + (current-brace containing-sexp)) > + (while (and (eq bufpos t) > + current-brace > + (not (memq current-brace c-no-bracelist-cache))) > + (when paren-state > + (setq next-containing (c-pull-open-brace paren-state))) > + > + (goto-char current-brace) > + (cond > + ((c-looking-at-inexpr-block next-containing next-containing) > + ;; We're in an in-expression block of some kind. Do not > + ;; check nesting. We deliberately set the limit to the > + ;; containing sexp, so that c-looking-at-inexpr-block > + ;; doesn't check for an identifier before it. > + (setq bufpos nil)) > + ((not (eq (char-after) ?{)) > + (setq bufpos nil)) > + ((eq (setq bufpos (c-looking-at-or-maybe-in-bracelist > + next-containing next-containing)) > + t) > + (setq current-brace > + next-containing > + next-containing nil)))) > + (cond > + ((and (consp bufpos) > + (or accept-in-paren (not (eq (cdr bufpos) 'in-paren)))) > + (car bufpos)) > + ((not (memq containing-sexp c-no-bracelist-cache)) > + ;; Update `c-no-bracelist-cache' > + (setq c-no-bracelist-cache (copy-tree whole-paren-state)) > + nil))))) > > (defun c-looking-at-special-brace-list () > ;; If we're looking at the start of a pike-style list, i.e., `({ })', > diff -r 2c1ba136f3f2 cc-mode.el > --- a/cc-mode.el Mon Oct 28 15:47:50 2024 +0000 > +++ b/cc-mode.el Fri Nov 29 23:12:27 2024 +0000 > @@ -2313,7 +2313,9 @@ > ;; The following must happen after the previous, which likely alter= s > ;; the macro cache. > (when c-opt-cpp-symbol > - (c-invalidate-macro-cache beg end))))) > + (c-invalidate-macro-cache beg end)) > + (setq c-no-bracelist-cache > + (c-whack-state-after beg c-no-bracelist-cache))))) > > (defvar c-in-after-change-fontification nil) > (make-variable-buffer-local 'c-in-after-change-fontification) > > > > > -- > > > mvh/best regards Bj=C3=B6rn Lindqvist > > -- > Alan Mackenzie (Nuremberg, Germany). --=20 mvh/best regards Bj=C3=B6rn Lindqvist