Subject: bug#78520: 31.0.50; Performance issue in dired+isearch with dired-isearch-filenames

From: Michael Heerdegen <[email-masked]>
Date: Tue, 27 May 2025 17:30:24 +0200

Juri Linkov <[email-masked]> writes:

> Unfortunately, I don't remember if this slower implementation is
> required for non-regexp case.  Maybe let's revert it for non-regexp.

A big part of the discussion was in Bug#14013.  I've read most of the
discussion again but found no clue.  So hopefully: no, not required.

I'm now looking at `search-within-boundaries'.  Do you think we could
fall back to a more efficient algorithm even when `subregexp' is nil
(that seems to work for me)?

For reference, I had been using something like this:

#+begin_src emacs-lisp
(defun my-search-within-boundaries--before-while-ad
    (f search-fun get-fun next-fun string &optional bound noerror count)
  "Search more efficiently when possible."
  (cl-flet ((search-with-slow-algorithm ()
              (funcall f search-fun get-fun next-fun string bound noerror count)))
    (if (and isearch-regexp
             ;; do we match the beginning or end of the line (a region)?
             (save-match-data
               (let ((subregexp (make-symbol "subregexp")))
                 (catch subregexp
                   (let ((i 0))
                     (while (string-match "\\^\\|\\$" string i)
                       (setq i (match-end 0))
                       (when (subregexp-context-p string (match-beginning 0))
                         ;; The ^/$ is not inside a char-range or escaped.
                         (throw subregexp t))))))))
        ;; we need to fall back to the slow procedure
        (search-with-slow-algorithm)
      (let ((old (point))
            (search-result nil))
        (unwind-protect
            (setq search-result
                  (and (save-match-data
                         (when (funcall (or search-fun
                                            (isearch-search-fun-default))
                                        string bound 'noeror)
                           (goto-char (if isearch-forward (match-beginning 0) (match-end 0)))
                           t))
                       (search-with-slow-algorithm)))
          (unless search-result (goto-char old)))))))

(advice-add 'search-within-boundaries :around #'my-search-within-boundaries--before-while-ad)
#+end_src

and didn't see any downside so far.

Michael.