Rudolf Adamkovič <[email protected]> writes: > [You forgot to CC the list; fixed here.]
Thank you! > It is objectively simpler than the proposed variant. Me, I would also > indent `string-width` below `nth` for maximum readability, and perhaps > even spell our `index`, making it as 101 as possible: Sure, good ideas, everything to increase readability! I tried once more, I am posting here the inline patch with a detailed description and a benchmark file for further tinkering for anyone interested. Best, -- Slawomir Grochowski
>From 500ac779eac1ce1504d299b1f270fa43f066167f Mon Sep 17 00:00:00 2001 From: Slawomir Grochowski <[email protected]> Date: Wed, 13 May 2026 16:06:22 +0200 Subject: [PATCH] org-colview: Use cl-loop in `org-columns--set-widths' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lisp/org-colview.el (org-columns--set-widths): Rewrite the inner loop using `cl-loop' with `for ... on ...' iteration over the format specs and the widths list. The previous attempt with `while' loop (from f06c61e41) achieved maximum speed by walking list pointers manually with `cdr', avoiding the O(k) cost of `nth' on singly-linked lists. The new variant keeps the same pointer-walking property - `for ... on ...' exposes the underlying cons cells, so `(car cons)' / `setcar' remain O(1) — while adopting the more idiomatic `cl-loop' form. The O(m) algorithmic improvement from f06c61e41 is preserved: the cache is still traversed only once. The earlier `cl-loop' attempt that was rejected in f06c61e41 relied on `(nth index widths)' which degraded performance to O(k) per access; the `for ... on ...' form avoids that pitfall entirely. Benchmark data (50 runs each, all widths auto-computed from cache): 10 columns (practical case — fits on screen without scrolling): Rows Cols Old O(n×m) cl-loop nth cl-loop on while Old/nth Old/on Old/while ────────────────────────────────────────────────────────────────────────────────────────────────── 10 10 0.00072 s 0.00019 s 0.00015 s 0.00013 s 3.7× 4.9× 5.6× 100 10 0.00183 s 0.00169 s 0.00140 s 0.00098 s 1.1× 1.3× 1.9× 300 10 0.00440 s 0.00502 s 0.00380 s 0.00338 s 0.9× 1.2× 1.3× 500 10 0.00705 s 0.00838 s 0.00633 s 0.00522 s 0.8× 1.1× 1.4× 1000 10 0.01360 s 0.02125 s 0.01569 s 0.01064 s 0.6× 0.9× 1.3× 20 columns (wider, for completeness): Rows Cols Old O(n×m) cl-loop nth cl-loop on while Old/nth Old/on Old/while ────────────────────────────────────────────────────────────────────────────────────────────────── 10 20 0.00084 s 0.00033 s 0.00027 s 0.00045 s 2.5× 3.1× 1.9× 100 20 0.00341 s 0.00340 s 0.00232 s 0.00218 s 1.0× 1.5× 1.6× 300 20 0.00864 s 0.01076 s 0.00804 s 0.00624 s 0.8× 1.1× 1.4× 500 20 0.01434 s 0.01601 s 0.01213 s 0.00998 s 0.9× 1.2× 1.4× 1000 20 0.02912 s 0.03506 s 0.03159 s 0.02042 s 0.8× 0.9× 1.4× The `cl-loop on' variant trails the `while' by ~10–20% on average, with measurement noise occasionally inverting the order. The trade-off favours readability: the `cl-loop' form expresses the parallel walk over three lists (triplets, specs, widths) much more clearly than three interleaved `setq ... (cdr ...)' updates. --- lisp/org-colview.el | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lisp/org-colview.el b/lisp/org-colview.el index 60ea55a8d..ab1e275f2 100644 --- a/lisp/org-colview.el +++ b/lisp/org-colview.el @@ -345,15 +345,14 @@ where: (`(,_ ,title . ,_) (string-width title)))) org-columns-current-fmt-compiled))) (dolist (entry cache) - (let ((triplets (cdr entry)) - (specs org-columns-current-fmt-compiled) - (w widths)) - (while (and triplets specs w) - (unless (wholenump (nth 2 (car specs))) - (setcar w (max (car w) (string-width (nth 2 (car triplets)))))) - (setq triplets (cdr triplets)) - (setq specs (cdr specs)) - (setq w (cdr w))))) + (cl-loop for triplet in (cdr entry) + for spec-cons on org-columns-current-fmt-compiled + for width-cons on widths + unless (wholenump (nth 2 (car spec-cons))) + do (setcar width-cons + (max (car width-cons) + (string-width + (nth 2 triplet)))))) (apply #'vector widths)))) (defun org-columns--new-overlay (beg end &optional string face) -- 2.39.5
bench-org-columns-set-widths.el
Description: application/emacs-lisp
