blob: aa433521e789eeed00eae5c8dd7362d872d357bd (
plain)
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
|
;;; perf-perspective.el --- Performance harness for Perspective -*- lexical-binding: t; -*-
;; Licensed under the same terms as Emacs and under the MIT license.
;; URL: http://github.com/nex3/perspective-el
;; Created: 2026-03-30
;;; Commentary:
;; This file provides an opt-in batch harness for comparing Perspective buffer
;; killing behavior across revisions. It is intentionally not part of the
;; default ERT suite.
;;
;; Run from the repository root with:
;;
;; make perf
;;
;; Or directly:
;;
;; emacs -Q --batch -L . -l test/perf-perspective.el --eval "(persp-perf-run)"
;;
;; Customize the run with:
;;
;; (let ((persp-perf-num-perspectives 16)
;; (persp-perf-buffers-per-perspective 24)
;; (persp-perf-temp-buffers-per-perspective 8)
;; (persp-perf-iterations 15))
;; (persp-perf-run))
;;; Code:
(require 'benchmark)
(require 'cl-lib)
(require 'perspective)
(defvar persp-perf-num-perspectives 12
"How many non-main perspectives to create for the performance harness.")
(defvar persp-perf-buffers-per-perspective 20
"How many ordinary buffers to create in each perspective.")
(defvar persp-perf-temp-buffers-per-perspective 6
"How many temporary buffers to create in each perspective.")
(defvar persp-perf-iterations 10
"How many times to run each benchmark scenario.")
(defun persp-perf--cleanup-buffers ()
"Kill all live buffers except the startup scratch buffer."
(let ((scratch (get-buffer "*scratch*")))
(dolist (buffer (buffer-list))
(when (and (buffer-live-p buffer)
(not (eq buffer scratch)))
(kill-buffer buffer)))))
(defmacro persp-perf--with-environment (&rest body)
"Run BODY in a fresh Perspective environment and clean up afterward."
(declare (indent 0))
`(let ((persp-suppress-no-prefix-key-warning t)
(persp-feature-flag-prevent-killing-last-buffer-in-perspective t))
(persp-perf--cleanup-buffers)
(persp-mode 1)
(unwind-protect
(progn ,@body)
(persp-mode -1)
(persp-perf--cleanup-buffers))))
(defun persp-perf--populate-perspectives ()
"Populate multiple perspectives with ordinary and temporary buffers."
(cl-loop for idx from 1 to persp-perf-num-perspectives do
(let ((persp-name (format "P%d" idx)))
(persp-switch persp-name)
(cl-loop for buf-idx from 1 to persp-perf-buffers-per-perspective do
(switch-to-buffer (format "*%s-buf-%02d*" persp-name buf-idx)))
(cl-loop for tmp-idx from 1 to persp-perf-temp-buffers-per-perspective do
(switch-to-buffer (format " %s-temp-%02d" persp-name tmp-idx)))))
(persp-switch "main"))
(defun persp-perf--scenario-unrelated-kill ()
"Kill a buffer from the current perspective while other perspectives are unrelated."
(persp-perf--with-environment
(persp-perf--populate-perspectives)
(let ((target (switch-to-buffer "*perf-target*")))
(switch-to-buffer "*perf-helper*")
(switch-to-buffer target)
(kill-buffer target))))
(defun persp-perf--scenario-shared-keeper ()
"Kill a shared buffer that must remain alive in another perspective."
(persp-perf--with-environment
(let ((ido-ignore-buffers '("^\\*scratch\\*")))
(persp-perf--populate-perspectives)
(let ((target (switch-to-buffer "*perf-target*")))
(persp-switch "P1")
(switch-to-buffer target)
(persp-switch "main")
(switch-to-buffer "*perf-helper*")
(switch-to-buffer target)
(kill-buffer target)))))
(defun persp-perf--benchmark (name function)
"Run benchmark NAME by calling FUNCTION `persp-perf-iterations' times."
(let ((result (benchmark-run persp-perf-iterations (funcall function))))
(message "%s" name)
(message " iterations: %d" persp-perf-iterations)
(message " elapsed: %.6fs" (nth 0 result))
(message " gc-count: %d" (nth 1 result))
(message " gc-elapsed: %.6fs" (nth 2 result))
(message "")))
(defun persp-perf-run ()
"Run the Perspective performance harness in batch mode."
(interactive)
(message "Perspective performance harness")
(message " perspectives: %d" persp-perf-num-perspectives)
(message " regular buffers / perspective: %d" persp-perf-buffers-per-perspective)
(message " temp buffers / perspective: %d" persp-perf-temp-buffers-per-perspective)
(message "")
(persp-perf--benchmark
"Scenario 1: kill buffer with unrelated other perspectives"
#'persp-perf--scenario-unrelated-kill)
(persp-perf--benchmark
"Scenario 2: kill shared buffer that another perspective must keep"
#'persp-perf--scenario-shared-keeper))
(provide 'perf-perspective)
;;; perf-perspective.el ends here
|