atlas-engineer / prompter

Live-narrowing, fuzzy-matching, extensible prompt framework.
BSD 3-Clause "New" or "Revised" License
13 stars 1 forks source link

Slow computation for 1M+ suggestions #23

Open aartaka opened 1 year ago

aartaka commented 1 year ago

I've got this code in my Nyxt config:

(define-class unicode-source (prompter:source)
  ((prompter:name "Unicode character")
   (prompter:filter-preprocessor #'prompter:filter-exact-matches)
   (prompter:constructor (loop for i from 0
                               while (ignore-errors (code-char i))
                               collect (code-char i)))))

(defmethod prompter:object-attributes ((char character) (source unicode-source))
  `(("Character" ,(if (graphic-char-p char)
                      (princ-to-string char)
                      (format nil "~s" char)))
    ("Name" ,(char-name char))
    ("Code" ,(format nil "~D/~:*~X" (char-code char)))))

(define-command-global insert-unicode (&key (character (prompt :prompt "Character to insert"
                                                               :sources 'unicode-source)))
  "Insert the chosen Unicode character."
  (ffi-buffer-paste (string character)))

When running the command, I usualy wait some 3-7 seconds for it to load, and the scrolling/narrowing is terribly laggy. Would be nice to optimize something on the Prompter side to make it work :)

Ambrevar commented 1 year ago

So there are at least 2 performance issues at play here: initialization and view computation.

For the first one, the bottleneck is ensure-suggestions-list which is called in initialize-instance :after of source:

(setf (slot-value source 'initial-suggestions)
            (ensure-suggestions-list source (initial-suggestions source)))

Multiple strategies:

aartaka commented 1 year ago

Yeah, maybe adding a toplevel (declaim (optimize speed)) won't hurt