Subject: bug#77089: [PATCH] Simplify Eshell history de-duplication

From: Morgan Smith <[email-masked]>
Date: Mon, 17 Mar 2025 18:33:50 -0400

Tags: patch

Hello!

I was noticing a perceptible delay in starting eshell of 0.838 seconds.
Turns out it was because I had `eshell-hist-ignoredups' set to 'erase
and I had a 5000 line shell-history file.

This patch speeds it up for me to 0.011 seconds.

>From 68160b6c84c2f8946caca5a6be274434f4e3d053 Mon Sep 17 00:00:00 2001
From: Morgan Smith <[email-masked]>
Date: Mon, 17 Mar 2025 18:19:21 -0400
Subject: [PATCH] Simplify Eshell history de-duplication

This also increases performance significantly for large history
files when `eshell-hist-ignoredups' is set to 'erase.

* lisp/eshell/em-hist.el (eshell-read-history): Run
`delete-duplicate-lines' on the shell history text instead of
checking for duplicates at every insertion.
---
 lisp/eshell/em-hist.el | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/lisp/eshell/em-hist.el b/lisp/eshell/em-hist.el
index 3f779f95acd..78ceed4bd6a 100644
--- a/lisp/eshell/em-hist.el
+++ b/lisp/eshell/em-hist.el
@@ -458,22 +458,17 @@ eshell-read-history
 	     (ignore-dups eshell-hist-ignoredups))
 	(with-temp-buffer
 	  (insert-file-contents file)
+          (when ignore-dups
+            (delete-duplicate-lines (point-min) (point-max) t
+                                    (not (eq ignore-dups 'erase))))
 	  ;; Watch for those date stamps in history files!
 	  (goto-char (point-max))
 	  (while (and (< count size)
 		      (re-search-backward "^[ \t]*\\([^#\n].*\\)[ \t]*$"
 					  nil t))
-	    (let ((history (match-string 1)))
-              (when (or (ring-empty-p ring)
-                        (null ignore-dups)
-                        (and (not (string-equal
-                                   (ring-ref ring (1- (ring-length ring)))
-                                   history))
-                             (not (and (eq ignore-dups 'erase)
-                                       (ring-member ring history)))))
-                (ring-insert-at-beginning
-		 ring (subst-char-in-string ?\177 ?\n history))
-                (setq count (1+ count))))))
+            (ring-insert-at-beginning
+             ring (subst-char-in-string ?\177 ?\n (match-string 1)))
+            (setq count (1+ count))))
 	(setq eshell-history-ring ring
 	      eshell-history-index nil
               eshell-hist--new-items 0))))))
-- 
2.48.1