;;; -*- lexical-binding: t -*- ;; ;; ----------------------------------------------------------------------------- ;; this file: ;; https://dataswamp.org/~incal/emacs-init/ll/ll-sum.el ;; ----------------------------------------------------------------------------- (require 'cl-lib) (cl-pushnew (expand-file-name ".") load-path :test #'string=) (require 'luki-lisp) ;; ----------------------------------------------------------------------------- (-> 'benchmark) ;; ----------------------------------------------------------------------------- ;; uses `goto-line-relative' ;; gives a byte-compiler warning, says interactive use only, ;; instead use `forward-line', the same is said in the help (with-no-warnings (defun ina (lne) (goto-line-relative lne))) ;; uses `goto-line' ;; same comments as `goto-line-relative' (with-no-warnings (defun alt (lne) (goto-line lne))) ;; non-relative restarter with `forward-line' ;; that is mentioned in the help favorably (defun doc (lne) (goto-char (point-min)) (forward-line lne)) ;; non-relative restarter with `goto-char' and `pos-bol' ;; hinted at in the help that it is even better (defun chr (lne) (goto-char (point-min)) (goto-char (pos-bol lne))) ;; relative non-restarter with `forward-line' and `line-number-at-pos'. I wrote ;; this to complete this investigation, but it is very fast, so they are right ;; saying use `forward-line', but for huge buffers it is the relative ;; non-restart that makes the difference (defun rel (lne) (forward-line (- lne (line-number-at-pos) -2))) ;; A relative non-restarter with `goto-char', `pos-bol', and `line-number-at-pos'. ;; The best by far. (defun gst (lne) (goto-char (pos-bol (- lne (line-number-at-pos) -1)))) ;; ----------------------------------------------------------------------------- (defun goto-liners-bench () (save-mark-and-excursion (cl-loop with lns = (number-sequence (line-number-at-pos (point-min)) (line-number-at-pos (point-max))) with rnd = (sort lns (L (_ __) (z (random (** 2 1))))) with fns = (list #'ina #'alt #'doc #'chr #'rel #'gst) with len = (--- fns) with tme = (make-list len 1.2) with its = (** 2 64) for l in rnd do (cl-loop for f in fns for i from 0 to len do (++ (nth i tme) (benchmark-elapse its (funcall f l)))) finally return (@f "%s\n funs %d lines %d iters/lne/fun 2^64 = %d %s%s%s%s" " ---------------------------------------------" len (--- lns) its "\n GNU Emacs benchmark.el by Dave Love 2003-2025" "\n ---------------------------------------------\n" (cl-subseq (@f " %s" (mapcar (L (p) (@f "\n ____ %s %.2f s" (1st p) (cdr p))) (cl-pairlis fns tme))) 2 -1) "\n\n ---------------------------------------------")))) ;; ----------------------------------------------------------------------------- (defun do-line-test () (i) (when-let* ((buf (get-buffer-create "*emeta*")) (_ (! (xref-find-definitions "gnus-summary-bookmark-jump"))) (_ (goto-end)) (res (goto-liners-bench))) (bury-buffer) (with-current-buffer buf (erase-buffer) (@i res) (pop-to-buffer buf) (goto-beg) (delete-other-windows)))) ;; (do-line-test) ;; ----------------------------------------------------------------------------- (defun sum-buffer-entries () (cl-loop with res = (make-hash-table) with fin = (point-max) with name = "" with scre = 0 while (< (point) fin) do (goto-char (pos-bol 2)) ; next line at BOL (when (re-search-forward "[[:alpha:]]+" (pos-eol) t) (setf name (match-string-no-properties 0)) (when (re-search-forward "[[:digit:]]+\.[[:digit:]]+" (pos-eol) t) 0.0 (setf scre (string-to-number (match-string-no-properties 0))) (when-let* ((intname (intern name)) (old-scre (gethash intname res 0))) (puthash intname (+ old-scre scre) res)))) finally return res)) ;; (sum-buffer-entries) ;; ----------------------------------------------------------------------------- ;; --------------- ;; 1st round score ;; --------------- ;; 1. home 12.7 ;; 2. sandra 11.6 ;; 3. dolls 11.6 ;; 4. bright 11.6 ;; 5. tri2 11.4 ;; 6. round 10.9 ;; 7. hot 10.9 ;; 8. curves 10.9 ;; --------------- ;; ;; --------------- ;; 2nd round score ;; --------------- ;; 1. you 11.7 ;; 2. are 11.5 ;; 3. a 12.0 ;; 4. dork 12.0 ;; 5. stop 10.3 ;; 6. reading 11.6 ;; 7. this 11.2 ;; 8. now 11.3 ;; --------------- ;; ;; --------------- ;; 3rd round score ;; --------------- ;; 1. incal 10.7 ;; 2. and 10.5 ;; 3. efti 10.0 ;; 4. are 10.0 ;; 5. in 10.3 ;; 6. their 10.6 ;; 7. own 10.2 ;; 8. league 10.3 ;; --------------- ;; ----------------------------------------------------------------------------- (<- 'll-sum) ;; -----------------------------------------------------------------------------