-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpel-benchmark.el
143 lines (123 loc) · 5.91 KB
/
pel-benchmark.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
;;; pel-benchmark.el --- Emacs benchmark reports. -*- lexical-binding: t; -*-
;; Created : Tuesday, September 1 2020.
;; Author : Pierre Rouleau <prouleau001@gmail.com>
;; Time-stamp: <2024-01-07 10:44:02 EST, updated by Pierre Rouleau>
;; This file is part of the PEL package.
;; This file is not part of GNU Emacs.
;; Copyright (C) 2020, 2021, 2023, 2024 Pierre Rouleau
;;
;; This program is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;; ----------------------------------------------------------------------------
;;; Commentary:
;;
;; This file contains Emacs benchmark utilities.
;;; ----------------------------------------------------------------------------
;;; Dependencies:
;;
;; This depends on some code being stored inside your init.el file.
;; See `pel-show-init-time' docstring.
(require 'pel--base)
(require 'pel-window)
(require 'pel-setup)
(eval-when-compile (require 'subr-x)) ; use: `string-join'
;;; ----------------------------------------------------------------------------
;;; Code:
;;
(defun pel-show-init-time (&optional log-it)
"Display benchmark startup time.
Display the benchmark initialization and duration tree in 2 buffers
if the benchmark-init external package is installed and available.
If the optional LOG-IT argument is non-nil then instead logs
the Emacs startup time, process mode, operation mode and Emacs version
into the pel-startup-time.log.txt file stored in the user-emacs-directory.
In both cases, also display the Emacs startup time.
Requires installation of the benchmark-init.
Use M-x list-package, select benchmark-init and install it.
Then update your init.el file and place the following lines as
close as possible to the top of the file:
;; -------------------------------------------------------------------------
;; Setup Benchmark Measurement
;; ---------------------------
;; Load benchmark right away using the file name explicitly so we can use it
;; to benchmark the complete package loading mechanism.
;; CAUTION:
;; - Copy the following files downloaded from MELPA into your PEL
;; utility directory which is normally ~/.emacs.d/utils:
;; - benchmark-init-modes.el and .elc
;; - benchmark-init.el and .elc
;; - Do not copy the benchmark-init-autoloads.el and the
;; nor the benchmark-init-pkg.el file.
;; They are not needed for PEL.
;; - Use to measure startup time and development of your init,
;; comment this code after your investigation and want to start
;; a little faster.
;;
(require \\='benchmark-init
(expand-file-name \"~/.emacs.d/utils/benchmark-init\"))
(add-hook \\='after-init-hook \\='benchmark-init/deactivate)
Update the path if necessary.
If the above lines are not written in your init.el this function only
prints the Emacs init time on the echo area."
(interactive "P")
(if log-it
(let ((filename (expand-file-name "pel-startup-time.log.txt"
user-emacs-directory))
(pel-operation-mode (pel--startup-mode)))
(with-temp-file filename
(auto-fill-mode -1)
(when (file-exists-p filename)
(insert-file-contents filename))
(goto-char (point-max))
(insert (format "%s | %-20s | %-20s | %-12s | Emacs %s%s on %s\n"
(format-time-string "%F %T")
(emacs-init-time)
(if pel-emacs-is-graphic-p "graphic mode" "terminal (TTY) mode")
pel-operation-mode
emacs-version
(pel-string-when (and pel-emacs-27-or-later-p
(boundp 'package-quickstart)
package-quickstart)
" using package-quickstart")
system-type))
(when (eq pel-operation-mode 'inconsistent)
(insert (format "- %s\n"
(string-join (nth 2 (pel--fast-setup-met-criteria))
"\n- "))))))
(when (and (fboundp 'benchmark-init/show-durations-tree)
(fboundp 'benchmark-init/show-durations-tabulated)
(memq 'benchmark-init/deactivate after-init-hook))
(delete-other-windows)
(split-window-below)
(pel-2-vertical-windows)
;; On Emacs 27 and before, max-specpdl-size default is 1000.
;; On Emacs 28 and later max-specpdl-size is not used,
;; max-lisp-eval-depth is used (default of 1600)
;;
;; When there's a lot of packages installed benchmark hits a limit
;; with 1000 and stops with a warning
;; "Variable binding depth exceeds max-specpdl-size".
;; Change the value for the duration of the benchmark dump.
(let ((max-lisp-eval-depth 2000))
(ignore-errors
(benchmark-init/show-durations-tree)
(other-window 1)
(benchmark-init/show-durations-tabulated)))))
(message "Emacs startup time: %s" (emacs-init-time)))
(defun pel-log-init-time ()
"Log Emacs init time in pel-startup-time.log.txt."
(interactive)
(pel-show-init-time t))
;;; ----------------------------------------------------------------------------
(provide 'pel-benchmark)
;;; pel-benchmark.el ends here