1 ;;; context-coloring-benchmark.el --- Benchmarks for context coloring -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2014-2015 Free Software Foundation, Inc.
5 ;; This file is part of GNU Emacs.
7 ;; This program is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation, either version 3 of the License, or
10 ;; (at your option) any later version.
12 ;; This program is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22 ;; Benchmarks for context coloring.
24 ;; Use with `make bench'.
28 (require 'context-coloring)
32 (defconst context-coloring-benchmark-path
33 (file-name-directory (or load-file-name buffer-file-name))
34 "This file's directory.")
36 (defun context-coloring-benchmark-resolve-path (path)
37 "Resolve PATH from this file's directory."
38 (expand-file-name path context-coloring-benchmark-path))
40 (defun context-coloring-benchmark-next-tick (callback)
41 (run-with-timer nil nil callback))
43 (defun context-coloring-benchmark-series (sequence callback)
44 "Call each function in SEQUENCE, then call CALLBACK. Each
45 function is passed a single callback parameter for it to call
54 (context-coloring-benchmark-next-tick
56 (context-coloring-benchmark-series
60 (defun context-coloring-benchmark-mapc (sequence iteratee callback)
61 "For each element in SEQUENCE, call ITERATEE, finally call
62 CALLBACK. ITERATEE is passed the current element and a callback
63 for it to call when it is done."
72 (context-coloring-benchmark-next-tick
74 (context-coloring-benchmark-mapc
79 (defun context-coloring-benchmark-log-results (result-file fixture statistics)
80 "Log benchmarking results to RESULT-FILE for fixture FIXTURE
85 (buffer-substring-no-properties (point-min) (point-max)))
87 (make-directory (context-coloring-benchmark-resolve-path "./logs") t)
90 (goto-char (point-min))
91 (insert (format "For fixture \"%s\":\n" fixture))
93 (insert "General statistics:\n")
94 (insert (format "File size: %s bytes\n" (plist-get statistics :file-size)))
95 (insert (format "Lines: %s\n" (plist-get statistics :lines)))
96 (insert (format "Words: %s\n" (plist-get statistics :words)))
97 (insert (format "Colorization times: %s\n"
98 (context-coloring-join
99 (mapcar (lambda (number)
100 (format "%.4f" number))
101 (plist-get statistics :colorization-times)) ", ")))
102 (insert (format "Average colorization time: %.4f\n"
103 (plist-get statistics :average-colorization-time)))
105 (insert "Function statistics:\n")
106 (insert "(Function Name / Call Count / Elapsed Time / Average Time):\n")
109 (buffer-substring-no-properties (point-min) (point-max)))
112 (defun context-coloring-benchmark (title setup teardown fixtures callback)
113 "Execute a benchmark titled TITLE with SETUP and TEARDOWN
114 callbacks. Measure the performance of all FIXTURES, calling
115 CALLBACK when all are done."
117 (elp-instrument-package "context-coloring-")
118 (let ((result-file (context-coloring-benchmark-resolve-path
119 (format "./logs/results-%s-%s.log"
120 title (format-time-string "%s")))))
121 (context-coloring-benchmark-mapc
123 (lambda (path callback)
124 (let ((fixture (context-coloring-benchmark-resolve-path path))
125 colorization-start-time
126 (colorization-times '())
131 (lambda (original-function)
135 (setq count (+ count 1))
136 (push (- (float-time) colorization-start-time) colorization-times)
140 (advice-remove #'context-coloring-colorize advice)
141 (context-coloring-benchmark-log-results
145 :file-size (nth 7 (file-attributes fixture))
146 :lines (count-lines (point-min) (point-max))
147 :words (count-words (point-min) (point-max))
148 :colorization-times colorization-times
149 :average-colorization-time (/ (apply #'+ colorization-times) 5)))
153 (setq colorization-start-time (float-time))
154 (context-coloring-colorize))))))))
155 (advice-add #'context-coloring-colorize :around advice)
156 (setq colorization-start-time (float-time))
157 (find-file fixture)))
160 (funcall callback)))))
162 (defconst context-coloring-benchmark-js-fixtures
163 '("./fixtures/jquery-2.1.1.js"
164 "./fixtures/lodash-2.4.1.js"
165 "./fixtures/async-0.9.0.js"
166 "./fixtures/mkdirp-0.5.0.js")
167 "Arbitrary JavaScript files for performance scrutiny.")
169 (defun context-coloring-benchmark-js-mode-run (callback)
170 "Benchmark `js-mode', then call CALLBACK."
171 (context-coloring-benchmark
174 "Preparation logic for `js-mode'."
175 (add-hook 'js-mode-hook #'context-coloring-mode))
177 "Cleanup logic for `js-mode'."
178 (remove-hook 'js-mode-hook #'context-coloring-mode))
179 context-coloring-benchmark-js-fixtures
182 (defun context-coloring-benchmark-js2-mode-run (callback)
183 "Benchmark `js2-mode', then call CALLBACK."
184 (context-coloring-benchmark
187 "Preparation logic for `js2-mode'."
188 (setq js2-mode-show-parse-errors nil)
189 (setq js2-mode-show-strict-warnings nil)
190 (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
191 (add-hook 'js2-mode-hook #'context-coloring-mode))
193 "Cleanup logic for `js2-mode'."
194 (remove-hook 'js2-mode-hook #'context-coloring-mode)
195 (setq auto-mode-alist (delete '("\\.js\\'" . js2-mode)
197 (setq js2-mode-show-strict-warnings t)
198 (setq js2-mode-show-parse-errors t))
199 context-coloring-benchmark-js-fixtures
202 (defconst context-coloring-benchmark-emacs-lisp-fixtures
203 '("./fixtures/lisp.el"
204 "./fixtures/faces.el"
206 "./fixtures/simple.el")
207 "Arbitrary Emacs Lisp files for performance scrutiny.")
209 (defun context-coloring-benchmark-emacs-lisp-mode-run (callback)
210 "Benchmark `emacs-lisp-mode', then call CALLBACK."
211 (context-coloring-benchmark
214 "Preparation logic for `emacs-lisp-mode'."
215 (add-hook 'emacs-lisp-mode-hook #'context-coloring-mode))
217 "Cleanup logic for `emacs-lisp-mode'."
218 (remove-hook 'emacs-lisp-mode-hook #'context-coloring-mode))
219 context-coloring-benchmark-emacs-lisp-fixtures
222 (defun context-coloring-benchmark-run ()
223 "Benchmark all modes, then exit."
224 (context-coloring-benchmark-series
226 #'context-coloring-benchmark-js-mode-run
227 #'context-coloring-benchmark-js2-mode-run
228 #'context-coloring-benchmark-emacs-lisp-mode-run)
232 (provide 'context-coloring-benchmark)
234 ;;; context-coloring-benchmark.el ends here