Open ThibautVerron opened 4 years ago
Further comments which I didn't know where to put in the formatted report. They might be helpful, but they aren't really more than uneducated guesses.
From what I can see in the report, there are a few sources of slowness.
The easiest to fix (and the least impactful) is the repeated calls to texmathp
. From what I can tell, most of those are not necessary, most pairs are either meaningful in both math and text, or only meaningful in math anyway.
The second is the listing of all possible pairs, both in all-pairs-to-insert
and in -show-pair-function
. I suspect that this is slow because there are a lot of pairs in LaTeX, compared to other modes.
To mitigate this (and yes, it goes opposite to what I wrote above), we could have two sets of pairs: those which are valid in text (very few) and those which are valid in maths. Then at least when typing text, there would be no looping over all maths pairs. But insertion of mathematics would still be slow.
Going further would require optimizing the lookup function, I guess.
And the third is in post-self-insert-hook-handler
, I don't know why. Is the output of all-pairs-to-insert
large enough that the subsequent loop is expensive?
Here is another profiler report, obtained after typing "This is some text and some more." a few times. There shouldn't be anything looking like the beginning of a pair in there, and definitely no pair. Yet smartparens does a non-trivial amount of work, including testing a few times whether we are in math mode.
- command-execute 5428 69%
- call-interactively 5418 69%
- funcall-interactively 5418 69%
- self-insert-command 4039 51%
- sp--post-self-insert-hook-handler 3969 50%
- sp--all-pairs-to-insert 1830 23%
- sp--do-action-p 979 12%
+ sp-get-pair 291 3%
+ sp-in-math-p 273 3%
+ sp-point-in-string 162 2%
+ sp-point-in-comment 94 1%
+ -flatten 46 0%
+ sp--looking-back-p 703 9%
sp--strict-regexp-quote 55 0%
- sp-insert-pair 1730 22%
- sp--pair-to-insert 1446 18%
- sp--all-pairs-to-insert 1438 18%
- sp--do-action-p 720 9%
+ sp-get-pair 247 3%
+ sp-in-math-p 195 2%
+ sp-in-string-quotes-p 52 0%
+ sp-point-in-string 51 0%
+ sp-latex-point-after-backslash 48 0%
+ sp-point-in-comment 32 0%
+ -flatten 20 0%
+ sp-text-mode-emoticon-p 15 0%
- sp--looking-back-p 614 7%
+ sp--looking-back 295 3%
#<compiled 0x1b9bee9> 8 0%
sp--strict-regexp-quote 48 0%
+ sp--get-closing-regexp 272 3%
I have run some tests without loading all the fancy pairs, and text insertion does feel faster, but still not to the point of, say, elisp. Again the profiler points to smartparens, with more of the work in the post-self-insert-hook-handler
.
So the length and complexity of the pairs list seems to play a role, but not exclusively.
For the record, doom disables a bunch of pairs for performance purposes:
It looks like the problem comes mainly from repeated calls to the slowpoke function texmathp
(via sp-in-math-p
). Based on my cursory glance at the code, for every inserted character, smartparens loops over all defined pairs and asks "is this pair allowed here?". For eight pairs, this check involves calling texmathp
: single/double quotes, \left
(w/ (
, [
, {
, |
), lvert
, and lVert
.
So, as a workaround, you could either disable these pairs (aside from single/double quotes) and let YASnippet handle them (like Doom does), or else get rid of the :when/:unless '(sp-in-math-p)
on all of these pairs:
(let ((modes '(tex-mode plain-tex-mode latex-mode LaTeX-mode)))
(dolist (pair '(("``" . "''")
("`" . "'")))
(sp-local-pair modes (car pair) (cdr pair)
:unless '(:rem sp-in-math-p)))
(dolist (pair '(("\\left(" . "\\right)")
("\\left[" . "\\right]")
("\\left{" . "\\right}")
("\\left|" . "\\right|")
("\\lVert" . "\\rVert")
("\\lvert" . "\\rvert")))
(sp-local-pair modes (car pair) (cdr pair)
:when '(:rem sp-in-math-p))))
For me, this second technique significantly improves the performance. Of course, it gets rid of the math-mode sanity check, but personally I don't care. A better long-term fix might involve caching the result of texmathp
?
Of course, it gets rid of the math-mode sanity check, but personally I don't care.
For left/right and so on, I cannot imagine a scenario where I would insert the text for one of those pairs in text mode and not want expansion. It can, on the other hand, happen that texmathp gets confused about the environment.
The test, though imperfect, might still be helpful for the quotes.
For me, this second technique significantly improves the performance.
If I remember correctly, I had tried a similar fix (but more rudimentary: redefining sp-in-math-p
to the constant true function). I did observe a speed-up, but not sufficient to make editing completely fluid.
let YASnippet handle them (like Doom does)
It's slightly off-topic, but I have not been able to find out how and where this is configured exactly. I only found one snippet handling \left(
/ \right)
.
For now I have disabled those pairs altogether and replaced them with a custom function, but I would very much like to have smartparens or yasnippet handle the corner cases for me.
See #1141 for a possible solution
Expected behavior
Normal, fluid text insertion.
Actual behavior
Typing text in LaTeX buffers feels slow and jumpy.
Steps to reproduce the problem
Open a LaTeX buffer, preferably on a slow-ish computer.
Copy/paste the following:
Place the point between
\begin{document}
and\end{document}
, and insert some text, for example (including automatic insertions):Backtraces if necessary (
M-x toggle-debug-on-error
)Backtraces not necessary, but here are relevant sections of profiler report for the above text:
Environment & version information
smartparens
version: be8d5c9major-mode
:latex-mode
M-x emacs-version
): GNU Emacs 26.3 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2019-12-03