Subject: Re: bug#48841: fido-mode is slower than ido-mode with similar settings

From: João Távora <[email-masked]>
Date: Sun, 13 Jun 2021 15:55:38 +0100

Dmitry Gutov <[email-masked]> writes:

>> Very interesting.  I don't know what the matter is with modifying
>> the
>> string itself.  Is it because we want to protect its 'face' property?
>> Maybe, but what's the harm in chaning it?
>
> I imagine it's just a "correctness" thing. Text properties are part of
> the string's identity. We add text properties, so we make a copy
> because we don't own the original list (it might be saved to some
> constant and also used for, I don't know, IMenu items?)

I just confirmed it's not for correctness.  If one foregoes the copy, in
fido-mode a C-h f followed by some input followed by C-g and an M-x and
no input (empty pattern) will show interesting results, i.e. a list of
propertized strings when nothing should be propertized.

But maybe that's a question of removing the propertization when the
pattern is empty?  I'll try later.

>> If we do want to protect the shared 'face' property -- and only 'face'
>> -- then we could very add some other property about face that the
>> frontend could read "just in time" before it itself makes a copy of the
>> string to display to the user.
>
> Yes, it's an option (though a less elegant one): apply some namespaced
> text properties with the necessary data. And then we'd also be able to
> fontify "just in time".
>
> Do we have any "frozen strings" in Emacs, which absolutely could not
> be modified? Do we plan to?

Immutable strings? And error when one tries to?  Or just ignore the
modification?  And how would that help here?

> I disagree it's a simpler technique, but it would indeed be a simpler
> change, based on the current implementation.

simpler means simpler in my book :-)

> But I don't mind it myself, and happy to update Company. Either way
> it's a step forward.

If Company and fido-mode and a couple more outside the core/Elpa are all
that's needed, it's probably warranted.  But there are so many frontends
right now, I don't know...  We'd need some "opt into the optimization",
I think."

>> But if the speedup is big, I'd revisit the rationale for requiring those
>> copies to be performed in the first place.
>
> With fido-vertical-mode, and with that particular input, it's
>
>   Elapsed time: 0.130773s (0.031547s in 1 GCs)
>
> without copy-sequence, and
>
>   Elapsed time: 0.169842s (0.069740s in 4 GCs)
>
> with it. Not game changing, but definitely measurable.

I don't have these results.  I tried the previous experiment:

   ;; C-u C-x C-e C-m in quick succession
   (benchmark-run (completing-read "bla" obarray))

And turned icomplete.el's while-no-input into a progn.

In an Emacs -Q where (length (all-completions "" obarray)) is about
20000.

   ;; with copy
   (0.39647753 6 0.22811240199999983)
   (0.431950471 7 0.263988651)
   (0.451116177 6 0.2249686070000001)
    
   ;; without copy, small but measurable speedup
   (0.29890632 2 0.08419541699999966)
   (0.293501099 2 0.08622194699999985)
   (0.306566633 3 0.0853211100000002)

In a loaded Emacs where (length (all-completions "" obarray)) is 64554

   ;; with copy
   (2.869362171 6 2.3882547280000495)
   (2.909661303 6 2.4209153659999743)
   (2.845522439 6 2.3638140250000106)
    
   ;; without copy.  Huge speedup.
   (0.79817337 1 0.4526993239999797)
   (0.8231736510000001 1 0.4752496449999626)
   (0.719004478 1 0.4016016420000028)

João