Dmitry Gutov writes: > but that can't be that reason. Indeed it isn't. But you're not far off, I think. Anyway, in the (completing-read "" obarray) scenario, the shortcut is taken, and that and the fact that the optimization then completing skips scoring for it -- which is blatantly wrong -- is why it is much faster. Looking at this, it seems that string-match with a non-group-capturing regexp over all the matches (the thing that the change was optimizing away) isn't that expensive in the overall gist of things. Thus in the C-h v case, the shortcut isn't taken and the optimization does what it should, but nothing gargantuan, around 8-9%. Also keep in mind this yoyo case is pretty contrived and I suspect more realistic cases would have even more modest gains. My attempts to fix the optimization to work correctly in all cases complicated the code and then slowed down the bare completion-read case. Not worth it IMO, therefore I have reverted it in the branch and in the latest patch I attach (lazy-hilit-2023-v4.diff). Here are the latest measurements for the "yoyo" test, now considering the C-h v scenario: ;; Daniel+Dmitry completin-read: 0.834s avg ;; Daniel+Dmitry C-h v: 0.988s avg ;; lazy-hilit completing-read: 0.825s avg ;; lazy-hilit C-h v: 0.946s avg Again, this shows my patch to be about 2-4% faster, though not really relevant. Again, the optimization I removed, if it were done correctly (which it wasn't) could maybe shave off another 8-9% off that. > But there are differences. The first is that the highlighter function > takes one string as an argument instead of a collection. I mentioned > this before, this will be much handier to use in company-capf. Don't fully follow this. Can you perhaps show two versions (or two snippets) of the company-capf code, the handy and the non-handy version? > Second, in Daniel's patch the "adjust metadata" function got a > different, arguably better, calling convention. That's not dependent > on the rest of the patch, so it can be considered separately. Maybe. Changes to calling convention can be argued for but, when possible, they shoudn't be in with performance improvements. > Third, it made a principled stance to avoid altering the original > strings, even the non-visual text properties. This approach could be > adopted piecewise from Daniel's patch, especially if the performance > ends up the same or insignificantly different in practical usage. If we really wanted to, we could also adopt the non-propertizing approach in my lazy-hilit patch, by calculating the score "just in time", much like Daniel's patch does it. But it should be clear that what we save in allocation in completion-pcm--hilit-commonality, we'll pay for in the same amount in consing later. So no performance benefit. And if we do that, don't forget there will be the ugly "unquoted" complication to deal with. Then again, in my understanding that complication is due to similar problem of mixing business and display logic. That's assuming I understand this comment in minibuffer.el correctly: ;; Here we choose to quote all elements returned, but a better option ;; would be to return unquoted elements together with a function to ;; requote them, so that *Completions* can show nicer unquoted values ;; which only get quoted when needed by choose-completion. So I would look into solving that first, instead of allowing the "unquoted" hacks to spread even further in minibuffer.el > As for whether we migrate to the completion-filter-completions API, I > don't have a strong opinion. If we still think that the next revision > of the completion API will be radically different, then there is not > much point in making medium-sized steps like that. OTOH, if we end up > with the same API for the next decade and more, > completion-filter-completions does look more meaningful, and more > easily extensible (e.g. next we could add a pair (completion-scorer > . fn) to its return value; and so on). And again, the implementation > could be a simple wrapper at first. I agree on some points, and looking at this from a API-convenience standpoint I note two things: * To get late highlighting in Daniel's patch, one has to use a whole new API entry function to gather completions, and another to fontify completions. One also deprecates an existing member of the API. * In my patch, one binds a new API varaible and uses a function to fontify completions. No deprecations. Even if it wasn't a much simpler change to minibuffer.el without any backward-compatibility gymnastics, I still think the latter is much cleaner and easier to implement for completion frontends. The fact that there's no deprecation of one of the most important members of the API to date makes it more confortable to understand IMO. João