From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Filipp Gunbin Newsgroups: gmane.emacs.bugs Subject: bug#51620: add-hook repeatedly adds same function into hook--depth-alist Date: Sat, 06 Nov 2021 02:26:32 +0300 Message-ID: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16039"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (darwin) To: 51620@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Nov 06 00:27:19 2021 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 1mj8cA-0003wz-01 for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 06 Nov 2021 00:27:19 +0100 Original-Received: from localhost ([::1]:43206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mj8c7-000487-PU for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 05 Nov 2021 19:27:16 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39964) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mj8bu-00047C-OL for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 19:27:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:36072) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1mj8bu-0001xv-GW for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 19:27:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1mj8bu-0007IE-Db for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 19:27:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Filipp Gunbin Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 05 Nov 2021 23:27:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 51620 X-GNU-PR-Package: emacs X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Original-Received: via spool by submit@debbugs.gnu.org id=B.163615480728008 (code B ref -1); Fri, 05 Nov 2021 23:27:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 5 Nov 2021 23:26:47 +0000 Original-Received: from localhost ([127.0.0.1]:47618 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mj8bf-0007Hg-9l for submit@debbugs.gnu.org; Fri, 05 Nov 2021 19:26:47 -0400 Original-Received: from lists.gnu.org ([209.51.188.17]:44792) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1mj8bd-0007HY-Bi for submit@debbugs.gnu.org; Fri, 05 Nov 2021 19:26:45 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:39882) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mj8ba-00043r-VD for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 19:26:43 -0400 Original-Received: from wout4-smtp.messagingengine.com ([64.147.123.20]:34077) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mj8bY-0001ib-My for bug-gnu-emacs@gnu.org; Fri, 05 Nov 2021 19:26:42 -0400 Original-Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailout.west.internal (Postfix) with ESMTP id 0E73C3201DA0 for ; Fri, 5 Nov 2021 19:26:36 -0400 (EDT) Original-Received: from mailfrontend1 ([10.202.2.162]) by compute5.internal (MEProxy); Fri, 05 Nov 2021 19:26:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.fm; h= from:to:subject:date:message-id:mime-version:content-type; s= fm1; bh=ZdqU6VqtO8zJ6c6pgla2FW1Ov/GwxSRzw5LKvzN42N8=; b=ILnx0jy8 4GX7pEMIo3Mdr68JxGIxVUSNf9OYvY2v6J1g7mW4xIncTTG5QIqzD4c7LQ9orJVO 5JL1Eamm7yhqx+uBS6bO48DEjxFGmJX6GGrd6eNenXH10RYc55tITY0aBnWwNiJM mpjn+9V7T+t/aZErEF5XOKBsffpVaRcq0sBlHgwYL3jKLgylS1bQQCEzNCn3Taog u/aJSRLrqVwVJ5IvgFRoGlIIwQa2cH9Ge1Z3X6Gp4yoLov0gryqXoE4XtCTwVPra +PxC4roO0rKp3HJmHFiwOV3sgKspc7MwpTAigtGhvkLfjeHi5ORJt501jWL7KuvV ctqAPqtqGq9+Jg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:message-id :mime-version:subject:to:x-me-proxy:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; bh=ZdqU6VqtO8zJ6c6pgla2FW1Ov/Gwx SRzw5LKvzN42N8=; b=EVx/l0PvBAZ6wU5UP9y5R2QAQ0Y8zbi3Yobb+C657Lz6P JD4DRQTkx87CIn2Wt62dBQ/jiXxZcrj/XiLljeMJaP170Qc/E0GAYOqwq+qIcWkU u4961ng9OM5MOAmhxLGd72G9ZSqLyOS3sy8vL/y4NySFETnkAergRsvDbdb9VnNH J4TSoa7saKB+wDxkGP1gcyaEkU51pg4roDdbz0iXjtFgf+meabtYSGvyvHMmeZwO ihU0cbh1j4ktOCvu77kry61nN5yeryjEM1xXWhRcChEDOrh/lCV0+iH2Da1L1XXE 1gE/HrRFGfB7wATLb+YZ3TiMricBXLi8uIvVGuwvg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrtdejgddtlecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhephffvufgffffkgggtsehttdertddtre dtnecuhfhrohhmpefhihhlihhpphcuifhunhgsihhnuceofhhguhhnsghinhesfhgrshht mhgrihhlrdhfmheqnecuggftrfgrthhtvghrnhepteekgffgjedujeekveehudetffduff ejuedtveevfeeuvefgieeiueeuleekuddunecuvehluhhsthgvrhfuihiivgeptdenucfr rghrrghmpehmrghilhhfrhhomhepfhhguhhnsghinhesfhgrshhtmhgrihhlrdhfmh X-ME-Proxy: Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Fri, 5 Nov 2021 19:26:35 -0400 (EDT) Received-SPF: pass client-ip=64.147.123.20; envelope-from=fgunbin@fastmail.fm; helo=wout4-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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" Xref: news.gmane.io gmane.emacs.bugs:219032 Archived-At: I have the following case: in my "javaimp" package I have code which scans java files "in the same project": (defun javaimp--get-directory-classes (dir) (when (file-accessible-directory-p dir) (seq-mapcat #'javaimp--get-file-classes (seq-filter (lambda (file) (not (file-symlink-p file))) (directory-files-recursively dir "\\.java\\'"))))) There're some perfomance problems to fix, so I started with measuring time via M-x benchmark. Surpisingly, I saw that with each run (in a large project) the time increased by 8 seconds or so. Profiling lead me to add-hook and the fix made in bug#46326. In short, javaimp--get-file-classes visits file in temp buffer and uses syntax-ppss to parse Java code. On a large project, this is done many times, and next invocation of javaimp--get-directory-classes does everything again (this is what I wanted to fix, as well as look at fewer things during parsing). So I stumbled into problem which perhaps goes unnoticed in normal file editing, where you don't process tens of thousands of files with syntax-ppss (which calls add-hook) repeatedly. For reference, syntax.el does this: (add-hook 'before-change-functions #'syntax-ppss-flush-cache ;; We should be either the very last function on ;; before-change-functions or the very first on ;; after-change-functions. This is what I get when I run my test: (length (get 'before-change-functions 'hook--depth-alist)) => 58063 (length (get 'before-change-functions 'hook--depth-alist)) => 65303 All elements are `(syntax-ppss-flush-cache . 99)'. A simple reproducer: - $ echo 'print("Hello world!");' > /tmp/hello.py - emacs -Q - C-x C-f /tmp/hello.py - M-: (length (get 'before-change-functions 'hook--depth-alist)), observe number N - revisit the same file via C-x C-v - M-: (length (get 'before-change-functions 'hook--depth-alist)), observe number N+1 - on each revisit the number increments Next, to the code. There was this change in the patch for bug#46326: > (when (or (get hook 'hook--depth-alist) (not (zerop depth))) > ;; Note: The main purpose of the above `when' test is to avoid running > ;; this `setf' before `gv' is loaded during bootstrap. > - (setf (alist-get function (get hook 'hook--depth-alist) > - 0 'remove #'equal) > - depth)) > + (push (cons function depth) (get hook 'hook--depth-alist))) (Probably the comment and the first test in "or" should have been removed with the change, but I'm not suggesting that because I'm suggesting restoring setf) setf with #'eq test would be a better option than push, because it won't repeatedly add the same (as in "eq") element, if we reach this code somehow. In our case we reach this code for each new buffer, because the check is: (unless (member function hook-value) and `before-change-functions' is of course buffer-local. So we keep pushing elements into (get hook 'hook--depth-alist) for each new buffer. And, unrelated to this, I fail to understand why copy-sequence is here in the code further down in add-hook, could someone please explain? (setq hook-value (sort (if (< 0 depth) hook-value (copy-sequence hook-value)) I suggest this one-liner, which fixes the problem for me, however I certainly need someone (Stefan M.?) to look at this. TIA, Filipp diff --git a/lisp/subr.el b/lisp/subr.el index 8ff403e113..2b8b6deeb0 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1868,7 +1868,7 @@ add-hook (when (or (get hook 'hook--depth-alist) (not (zerop depth))) ;; Note: The main purpose of the above `when' test is to avoid running ;; this `setf' before `gv' is loaded during bootstrap. - (push (cons function depth) (get hook 'hook--depth-alist))) + (setf (alist-get function (get hook 'hook--depth-alist) 0) depth)) (setq hook-value (if (< 0 depth) (append hook-value (list function)) In GNU Emacs 28.0.60 (build 4, x86_64-apple-darwin20.6.0, NS appkit-2022.60 Version 11.6 (Build 20G165)) of 2021-11-05 built on fgunbin.local Repository revision: d8c9a9dc23e0c6f38c5138cb8fbb4109a5729a35 Repository branch: emacs-28 System Description: macOS 11.6 Configured using: 'configure --enable-check-lisp-object-type --with-file-notification=no' Configured features: ACL GLIB GNUTLS LCMS2 LIBXML2 MODULES NS PDUMPER PNG RSVG THREADS TOOLKIT_SCROLL_BARS XIM ZLIB