Emacs Lisp: Benchmark, Test Speed

By Xah Lee. Date: . Last updated: .
benchmark-run
(benchmark-run &optional REPETITIONS &rest FORMS)

Time execution of FORMS.

If REPETITIONS is supplied as a number, run FORMS that many times, accounting for the overhead of the resulting loop. Otherwise run FORMS once.

Return a list of the total elapsed time for execution, the number of garbage collections that ran, and the time taken by garbage collection. See also benchmark-run-compiled .

Emacs Lisp Benchmark Example: Byte Compiled Code

;; -*- coding: utf-8; lexical-binding: t; -*-
;; 2023-08-07
;; comparing speed of compiled code

(require 'benchmark)

(defun xtest (n)
  "Return the time, in seconds, to run N iterations of a loop."
  (while (> (setq n (1- n)) 0))
  n
  )

(setq xi (expt 10 7))

(benchmark-run 1 (xtest xi))
;; (0.7 0 0.0)

;; using benchmark-run-compiled does not make a difference. strange
(benchmark-run-compiled 1 (xtest xi))
;; (0.6 0 0.0)

;; actually compile the code make a difference
(byte-compile 'xtest)
(benchmark-run 1 (xtest xi))
;; (0.1 0 0.0)

;; bytecompiled code is some 7 times faster in this example

current-word vs get-thing-at-point

;; -*- coding: utf-8; lexical-binding: t; -*-
;; 2023-08-02 2023-08-07
;; comparing speed of ways to get current word

(require 'benchmark)

(setq xi 100000)

(benchmark-run xi (current-word))
;; some
;; (0.19 7 0.15)

(benchmark-run xi (xah-get-thing-at-point 'word))
;; some
;; (0.55 14 0.33)

;; byte compiled version
(benchmark-run xi (xah-get-thing-at-point 'word))
;; some
;; (0.24 5 0.11)

(benchmark-run xi (thing-at-point 'word))
;; some
;; (1.1 28 0.6)

Emacs Lisp Benchmark Example: diff ways of checking the char before cursor is any of whitespace

;; -*- coding: utf-8; lexical-binding: t; -*-
;; 2023-08-02
;; comparing speed of diff ways of checking the char before cursor is any of whitespace

(require 'benchmark)

(setq xi (expt 10 6))

(benchmark-run xi
  (progn
    (or
     (eq (char-before) 32)
     (eq (char-before) 9)
     (eq (char-before) 10))))
;; (0.21 0 0.0)

(benchmark-run xi
  (if (eq (point-min) (point))
      nil
    (prog2
        (backward-char)
        (looking-at "[ \t\n]")
      (forward-char))))
;; (0.43 0 0.0)

(benchmark-run xi
  (string-match "[ \t\n]" (char-to-string (char-before))))
;; (0.73 20 0.47)

(benchmark-run xi (looking-back "[ \t\n]"))
;; (1.5 43 1.0)

(benchmark-run xi (looking-back "[ \t\n]" (1- (point))))
;; (1.6 42 1.0)

Emacs Lisp Benchmark Example: Remove Prefx String

;; speed of replace a prefix string

(setq
 xstr "file:///C:/Users/xah/web/xahlee_info/emacs/emacs/elisp_benchmark.htmlfile:///"
 xpre "file:///"
 )

;; using builtin
(benchmark-run 10000
  (require 'subr-x)
  (string-remove-prefix xpre xstr))
;; (0.007 0 0.0)
;; (0.006 0 0.0)
;; (0.029 1 0.02)
;; (0.031 1 0.02)
;; (0.030 1 0.02)

;; manual string manipulation
(benchmark-run 10000
  (let (xhead)
    (setq xhead (substring xstr 0 (length xpre)))
    (if (string-equal xpre xhead)
        (progn (substring xstr (length xhead)))
      xstr)))
;; (0.005 0 0.0)
;; (0.007 0 0.0)
;; (0.029 1 0.02)
;; (0.030 1 0.02)

;; use replace-regexp-in-string
(benchmark-run 10000
  (let (xhead)
    (replace-regexp-in-string (concat "^" xpre) "" xstr t t)))
;; (0.06 2 0.04)

;; use a temp buffer
(benchmark-run 10000
  (let (xhead)
    (with-temp-buffer
      (insert xstr)
      (goto-char (point-min))
      (when (search-forward xpre nil t)
        (delete-region (point-min) (point)))
      (buffer-substring (point-min) (point-max)))))
;; (0.246684 6 0.13)

Emacs Lisp Benchmark Example: Test a Script

(benchmark-run 1 (xahsite-update-search))
;; (15.871795 34 0.7105949999999996)
;; (15.694725 35 0.7229780000000003)

Emacs Lisp Benchmark Example: insert per list item vs join list and insert once

;; 2024-01-24
;; compare the speed of inserting huge list into a buffer
;; insert one item at a time
;; vs
;; mapconcat and insert just once

;; conclusion: insert just once is a magnitude faster.
;; the more items, the more slow is insert per item

(setq xpaths nil)
(dotimes (i 2000 xpaths) (push (number-to-string i) xpaths))

(benchmark-run 10
  (let ((xbuf (get-buffer-create "xx888" t)))
    (with-current-buffer xbuf
      (erase-buffer)
      (mapc (lambda (x) (insert x "\n")) xpaths))
    (display-buffer xbuf)))
;; (0.1 0 0.0)

(benchmark-run 10
  (let ((xbuf (get-buffer-create "xx888" t)))
    (with-current-buffer xbuf
      (erase-buffer)
      (insert (mapconcat 'identity xpaths "\n")))
    (display-buffer xbuf)))
;; (0.001 0 0.0)