From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: Loading a package applies automatically to future sessions? Date: Sun, 28 Jan 2018 17:11:07 -0500 Message-ID: References: <76b1fb81-54c0-c213-a542-dc7b9838c473@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1517177387 14586 195.159.176.226 (28 Jan 2018 22:09:47 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sun, 28 Jan 2018 22:09:47 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: John Wiegley , George Plymale II , emacs-devel To: Radon Rosborough Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sun Jan 28 23:09:43 2018 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1efv8Z-0001vA-Ip for ged-emacs-devel@m.gmane.org; Sun, 28 Jan 2018 23:09:19 +0100 Original-Received: from localhost ([::1]:40867 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efvAa-0003BV-9H for ged-emacs-devel@m.gmane.org; Sun, 28 Jan 2018 17:11:24 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42698) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efvAS-0003B7-MK for emacs-devel@gnu.org; Sun, 28 Jan 2018 17:11:18 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1efvAP-0001mk-GQ for emacs-devel@gnu.org; Sun, 28 Jan 2018 17:11:16 -0500 Original-Received: from pruche.dit.umontreal.ca ([132.204.246.22]:39164) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1efvAP-0001m4-Au for emacs-devel@gnu.org; Sun, 28 Jan 2018 17:11:13 -0500 Original-Received: from ceviche.home (lechon.iro.umontreal.ca [132.204.27.242]) by pruche.dit.umontreal.ca (8.14.7/8.14.1) with ESMTP id w0SMB8R9005896; Sun, 28 Jan 2018 17:11:09 -0500 Original-Received: by ceviche.home (Postfix, from userid 20848) id 7570966271; Sun, 28 Jan 2018 17:11:07 -0500 (EST) In-Reply-To: (Radon Rosborough's message of "Sun, 28 Jan 2018 09:32:45 -0800") X-NAI-Spam-Flag: NO X-NAI-Spam-Threshold: 5 X-NAI-Spam-Score: 0 X-NAI-Spam-Rules: 2 Rules triggered EDT_SA_DN_PASS=0, RV6209=0 X-NAI-Spam-Version: 2.3.0.9418 : core <6209> : inlines <6344> : streams <1777377> : uri <2581543> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 132.204.246.22 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:222281 Archived-At: >> This said, if a package's activation gets in the way of the user, I'd >> generally consider it to be a bug in that package (similar to the fact >> that if (require ) has undesirable effects it's usually a bug in >> ). > Activation of packages is a significant performance hit. > It's therefore not a good idea to be activating superfluous packages. > JW has told me that one of the reasons his Emacs configuration does > not use package.el is that activating packages was too slow. The performance impact is indeed something that probably deserves a bit more work. But we need to clarify what are the expected use cases and sources of problems. E.g.: - In the case of JW, why does he have so many packages installed to slow down his startup, yet he doesn't want them activated? Are these packages that he does use, but just rarely? Or does he just have lots of packages installed that he doesn't use (e.g. that's my case: I always have all GNU ELPA packages installed, even though I use very few of them)? If so, why does he have so many packages installed even tho he doesn't use them? - In my case I have around 200 packages installed and I measured the startup cost of package-initialize to be 0.9s (with a warm cache). That's plenty fast for my use case (where I rarely start a new Emacs session), but I understand it may not be for people who like to use Emacs for quick one-off editing sessions. Still, what kind of slowdown is JW talking about: is it also in the order of 1s? more? If the slowdown is significant, could it be due to packages that do "too much work" in the -autoloads.el or is it really just the sheer number of -autoloads.el and -pkg.el to process? The issue came up recently on stackexchange and I whipped up a quick&dirty patch to experiment (see below) which shows that my 0.9s can be brought down to 0.3s by pre-computing a "big autoloads file", which can then be brought down to 0.2s by loading it with load-source-file-function bound to nil and can be reduced further to 0.1s by byte-compiling it. Another thing we could do is add support for activating a package without calling package-initialize beforehand (since just calling (package-initialize t) can already take a non-negligible amount of time, reading all the -pkg.el files). This way, a user could simply skip package-initialize completely and just "manually" activate those few packages he wants to activate. It should be fairly easy to implement. Stefan diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 71d1c41ec3..63ec6f40f7 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -676,6 +676,8 @@ package--activate-autoloads-and-load-path (defvar Info-directory-list) (declare-function info-initialize "info" ()) =20 +(defvar package--fastpath-pkgs t) + (defun package--load-files-for-activation (pkg-desc reload) "Load files for activating a package given by PKG-DESC. Load the autoloads file, and ensure `load-path' is setup. If @@ -718,16 +720,19 @@ package-activate-1 (message "Unable to activate package `%s'.\nRequired package `= %s-%s' is unavailable" name (car req) (package-version-join (cadr req))) (throw 'exit nil)))) - (package--load-files-for-activation pkg-desc reload) - ;; Add info node. - (when (file-exists-p (expand-file-name "dir" pkg-dir)) - ;; FIXME: not the friendliest, but simple. - (require 'info) - (info-initialize) - (push pkg-dir Info-directory-list)) - (push name package-activated-list) - ;; Don't return nil. - t))) + (if (listp package--fastpath-pkgs) + ;; We're only collecting the set of packages to activate! + (push pkg-desc package--fastpath-pkgs) + (package--load-files-for-activation pkg-desc reload) + ;; Add info node. + (when (file-exists-p (expand-file-name "dir" pkg-dir)) + ;; FIXME: not the friendliest, but simple. + (require 'info) + (info-initialize) + (push pkg-dir Info-directory-list)) + (push name package-activated-list) + ;; Don't return nil. + t)))) =20 (declare-function find-library-name "find-func" (library)) =20 @@ -3468,6 +3473,49 @@ package-list-packages-no-fetch (interactive) (list-packages t)) =20 +;;;; Fast-path for activation! + +(defcustom package-fastpath-file (locate-user-emacs-file "package-fastpath= .el") + "Location of the file used to speed up activation of packages at startup= ." + :type 'file) + +(defun package-fastpath-refresh () + "(Re)Generate the `package-fastpath-file'." + (interactive) + (package-initialize 'no-activate) + (let ((package--fastpath-pkgs ()) + ;; Pretend we haven't activated anything yet! + (package-activated-list ())) + (dolist (elt package-alist) + (condition-case err + (package-activate (car elt)) + ;; Don't let failure of activation of a package arbitrarily stop + ;; activation of further packages. + (error (message "%s" (error-message-string err))))) + (with-temp-file package-fastpath-file + (insert ";;; FastPath file to speed up package activation at startup= -*- lexical-binding:t -*-\n") + (insert ";; =A1=A1 This file is autogenerated, DO NOT EDIT !!\n\n") + (dolist (pkg package--fastpath-pkgs) + (let* ((file (locate-library (package--autoloads-file-name pkg))) + (pfile (prin1-to-string file))) + (insert "(let ((load-file-name " pfile "))\n") + (insert-file-contents file) + (while (search-forward "#$" nil 'move) + (replace-match pfile t t)) + (unless (bolp) (insert "\n")) + (insert ")\n"))) + (pp `(setq package-activated-list + (append ',(mapcar #'package-desc-name package--fastpath-p= kgs) + package-activated-list)) + (current-buffer)) + (insert " +;; Local Variables: +;; version-control: never +;; no-byte-compile: nil +;; no-update-autoloads: t +;; End: +")))) + (provide 'package) =20 ;;; package.el ends here