Open ChoppinBlockParty opened 5 years ago
I don't have enough data to debug this. Please dump comint-input-ring
to a file and attach it.
It is possible just to duplicate your history file until you get 30k lines.
I think I'm able to reproduce something that's related to this issue.
It only happens when counsel-shell-history
is configured to use ivy--regex-fuzzy
.
Here are my params related to ~/.bash_history
:
(length (ring-elements comint-input-ring))
;; => 1707
(apply 'max (mapcar 'length (ring-elements comint-input-ring)))
;; => 463
The second part is the most important: one of the commands on history is very long, which makes regex matching very slow. This cannot be mitigated in a good way, I think. Take, for instance:
(setq s1
(car (reverse
(cl-sort (ring-elements comint-input-ring) #'<
:key #'length))))
(length s1)
;; => 463
(setq r1 (ivy--regex-fuzzy "sandboxls"))
;; => "\\(s\\).*?\\(a\\).*?\\(n\\).*?\\(d\\).*?\\(b\\).*?\\(o\\).*?\\(x\\).*?\\(l\\).*?\\(s\\)"
(benchmark-run 100
(string-match-p r1 s1))
;; => (5.6352934569999995 0 0.0)
We can imagine how much backtracking has to happen with that regex on a string of length 463. It takes 0.05s just to match that single string once with that input. But we can have many more strings like that on our history, maybe hundreds or thousands.
One work around is to e.g. remove strings with length more than 100 from history:
(defun counsel--browse-history (elements)
"Use Ivy to navigate through ELEMENTS."
(setq ivy-completion-beg (point))
(setq ivy-completion-end (point))
(let ((cands
(cl-remove-if (lambda (s) (> (length s) 100))
(delete-dups
(when (> (ring-size elements) 0)
(ring-elements elements))))))
(ivy-read "Symbol name: " cands
:action #'ivy-completion-in-region-action
:caller 'counsel-shell-history)))
Let me know if this results in a speedup for you.
I have the following configuration on my shell-mode
I am using flx fuzzy matcher, it works very well even on sets like 100k. However, on shell history it can completely freeze emacs and burn all 100% CPU even with small input, like 3 chars, and a set of 29k history lines. What can it be? Can it be relevant to
comint-input-ring-separator
? How can I improve it? I have being using fzf in zsh for the same job for months, never even had a slightest noticable delay.