Open JasonGross opened 8 years ago
This is kind-of important; I'm hitting this natively in Fiat. The timings for
Time Redirect "/tmp/coq266857Co" Print Ltac Signatures.
Time Redirect "/tmp/coq266857Co" Timeout 1 Print Grammar tactic.
Time Add Search Blacklist "Raw" "Proofs".
Time Set Search Output Name Only.
Time Redirect "/tmp/coq26685INu" SearchPattern _.
Time Redirect "/tmp/coq26685VX0" SearchAbout -"____".
Time Remove Search Blacklist "Raw" "Proofs".
Time Unset Search Output Name Only.
are:
Finished transaction in 0.003 secs (0.004u,0.s) (successful)
Finished transaction in 0.004 secs (0.004u,0.s) (successful)
Finished transaction in 0. secs (0.u,0.s) (successful)
Finished transaction in 0. secs (0.u,0.s) (successful)
Finished transaction in 0.139 secs (0.14u,0.s) (successful)
Finished transaction in 0.141 secs (0.132u,0.008s) (successful)
Remove Search Blacklist "Raw" "Proofs".
Finished transaction in 0. secs (0.u,0.s) (successful)
A quarter of a second is really noticeable and makes the entire experience feel sluggish, especially if I get it after every Ltac
definition and things like idtac
.
At the very least, can you make it so that rather than querying after each definition, you query in the background when the user starts typing something that might need to be autocompleted. (There are two requests here: (1) don't block the UI while querying these things and (2) only query if you haven't yet queried since the last evaluated sentence and also the user just typed a character that might feed into the autocompleter.)
I have noticed this lag, too - and it is annoying enough that I turn off Company-Coq mode at times just to eliminate it. If you can't easily eliminate it, is there a way to just turn off that part of Company-Coq?
At the very least, can you make it so that rather than querying after each definition, you query in the background when the user starts typing something that might need to be autocompleted.
No, I can't: what takes time is to process the large number of definitions that Coq is returning. I think I could make it a bit better, but the single-threadedness of Emacs Lisp will still bite us.
only query if you haven't yet queried since the last evaluated sentence and also the user just typed a character that might feed into the autocompleter.
I'm not sure. Do you think it would be better to block the UI while typing, rather than right after processing a definition?
If you can't easily eliminate it, is there a way to just turn off that part of Company-Coq?
Do you have the live-on-the-edge
option on?
Do you have the
live-on-the-edge
option on?
No. Should I turn it on? The relevant bits of my ~/.emacs
are:
(defun my-coq-hook ()
(local-set-key (kbd "C-c RET") 'proof-goto-point)
(set-input-method "Agda")
(company-coq-initialize)
(setq company-coq-extra-symbols-cmd "SearchAbout -\"____\"")
(setq coq-end-goals-regexp-show-subgoals nil)
)
(add-hook 'coq-mode-hook 'my-coq-hook)
(global-set-key (kbd "C-c C-a C-u") #'company-coq-diff-unification-error)
(setq company-coq-dynamic-autocompletion t)
(add-hook 'company-coq-mode-hook
(lambda ()
(define-key company-coq-map (kbd "<backtab>") nil) ; disable collapsing on S-TAB
(defconst company-coq-tg--preprocessor-substitutions
'(("\n" . " ") ("[ " . "( OR-GROUP ") (" ]" . " )")
(" | " . " OR ") ("; " . " AND ") ("'" . "’")))
(define-key company-active-map [remap company-complete-common] #'company-indent-or-complete-common)))
(setq company-coq--use-special-set-unset-test-regexp t)
(setq company-coq-dynamic-autocompletion t)
Do you think it would be better to block the UI while typing, rather than right after processing a definition?
No. Can you set it up to block the UI only when the user hasn't given emacs any keyboard input for at least a second, and it's been at least a second since the last command finished processing. If the user hasn't paused in typing for a second and you need to give autocomplete feedback, display a warning in the status bar that says something like "Warning: Using outdated cached definitions for autocomplete. Press
No. Should I turn it on? The relevant bits of my ~/.emacs are:
(setq company-coq-dynamic-autocompletion t)
No; turning it off would help. That is, disabling dynamic autocompletion would help. These performance issues are the reason why I'm not graduating this to a by-default option :/
No. Can you set it up to block the UI only when the user hasn't given emacs any keyboard input for at least a second, and it's been at least a second since the last command finished processing.
I guess I could. I just need to find the time to implement it. But it's a bit tricky to get right: I need to find a time when it's safe to send input to Coqtop, and that's not trivial.
Can you set it up to block the UI only when the user hasn't given emacs any keyboard input
Note that something like this might already be implemented for code highlighting, I believe. If you stick a comment character in and keep typing, there's a delay before the color changes for the whole file, and it seems like it might be dependent on when you stop typing?
But it's a bit tricky to get right: I need to find a time when it's safe to send input to Coqtop, and that's not trivial.
How about this? Have a variable waiting-to-update-cache
. When you send document stuff to Coq, set it to false. In the place where you currently send your extra commands, instead set it to true, and reset the timer. Any time the user sends keystrokes to emacs, reset the timer. When the timer goes off (a second later, or whatever), if waiting-to-update-cache
is true, then query for the things you want.
That's not the issue. The issue is that there may already be a query in flight (from PG), and sending more stuff to Coq breaks everything in that case :/
Note that something like this might already be implemented for code highlighting, I believe
Yup, this is call idle timers in ELisp parlance :)
How does inline-docs (M-f12
?) work without breaking everything, then?
@cpitclaudel poke This is still way too slow. I'm hitting cases where it takes > 9 seconds to fetch symbol data.
Somehow, when I do M-x company-coq-toggle-definition-overlay
, company Coq gives me user-error: No information found for ‘make_Synthesis_package’. Try starting Coq, or waiting for processing to complete.
(or similar) if and only if there's currently a command in flight. Any update on getting this implemented for symbol fetching? Evaluating to, e.g., line 5 of src/Specific/X25519/C64/Synthesis.v
on branch zzz-slow-company-coq
in my fork of fiat-crypto with Coq 8.7+beta1, I get
Time Redirect "c:/Users/Jason/AppData/Local/Temp/coq107449_m" Print Ltac Signatures. (* Finished transaction in 0.928 secs (0.u,0.s) (successful) *)
Time Print Grammar tactic. (* Finished transaction in 0.298 secs (0.u,0.s) (successful) *)
Time Add Search Blacklist "Raw" "Proofs". (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Set Search Output Name Only. (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Redirect "c:/Users/Jason/AppData/Local/Temp/coq10744KKt" SearchPattern _. (* Finished transaction in 9.191 secs (0.281u,0.062s) (successful) *)
Time Remove Search Blacklist "Raw" "Proofs". (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Unset Search Output Name Only. (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Print LoadPath. (* Finished transaction in 0.189 secs (0.u,0.s) (successful) *)
Sorry, this slid off my radar. But rereading through the thread, I'm confused. If symbol loading takes 9 seconds on your machine, why would launching the loading after a few seconds improve things? Instead of predictable 10-seconds freezes, you'd get 10-seconds unpredictable ones, right? Are you installing company-coq from source or from MELPA?
I believe my usage pattern is strongly clustered around a very short delay between commands, with a long tail. If 90% of the time that I edit a file within 2 minutes of my last keystroke‡, I edit it within 5 seconds of my last keystroke, then the right approximation here is to delay the autocompletion-launching for ~5 seconds. This way, I won't be bogged down by slowness 90% of the time. (The delay time should be settable in ~/.emacs
.) Having emacs lag a bit when I've been spending the past 10 seconds trying to figure out what to do isn't that bad. Having emacs lag a lot between every single command execution makes coding unbearable.
Another optimization I'd like here is that company-coq fetching information from Coq should not prevent me from editing unlocked portions of the document, in the same way that telling PG to evaluate to a particular point doesn't prevent me from editing, even while Coq is spinning.
From MELPA.
‡ Actually "last keystroke" should be "the more recent of my last keystroke, and of Coq finishing execution of the document"
Another optimization I'd like here is that company-coq fetching information from Coq should not prevent me from editing unlocked portions of the document, in the same way that telling PG to evaluate to a particular point doesn't prevent me from editing, even while Coq is spinning.
The problem is that we're running (synchronous) Lisp code, not waiting for Coq.
What about the following: if we detect a keystroke or something like that while fetching completions, we cancel the whole process and return control to you immediately. This just cancels the loading, essentially.
if we detect a keystroke or something like that while fetching completions, we cancel the whole process and return control to you immediately
Sounds good! (Assuming that emacs doesn't hang on trying to abort Coq's execution of the command (which it frequently does when I try to break, or tell it to quit Coq).)
Ok, I think I can look at this next week, when I come back to the US. Please remind me in person?
Thanks, will do
On Tue, Oct 10, 2017, 5:53 AM Clément Pit-Claudel notifications@github.com wrote:
Ok, I think I can look at this next week, when I come back to the US. Please remind me in person?
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/cpitclaudel/company-coq/issues/131#issuecomment-335421845, or mute the thread https://github.com/notifications/unsubscribe-auth/AAYLLPgkx42u2MZYVjVyAU-Cl3dgL9VSks5sqz6LgaJpZM4Jn1Z8 .
Here are some backtraces: 1.
Debugger entered--Lisp error: (quit)
redisplay_internal\ \(C\ function\)()
2.
company-coq: Loading symbols…
Error running timer `company-coq-maybe-reload-each': (error "Proof General: quit in proof-shell-wait")
Quit
3.
company-coq: Loading symbols…
Error running timer `company-coq-maybe-reload-each': (error "Proof General: quit in proof-shell-wait")
Quit
(There doesn't seem to really be a backtrace....)
Ah, snap. The backtraces you show are points during which PG is busy-waiting for Coq to finish writing out the list of all identifiers. I don't think there's a good way to interrupt this from company-coq, but it could be done from PG. Sounds tricky, though. Let's check: how long do each of the following Redirect commands take in one of your files?
Add Search Blacklist "Raw" "Proofs".
Set Search Output Name Only.
Redirect "/tmp/coq14243Gze" SearchPattern _.
Redirect "/tmp/coq14243T9k" SearchAbout -"____".
Remove Search Blacklist "Raw" "Proofs".
Unset Search Output Name Only.
In a file close to the end, but not at the end of the pipeline:
Time Add Search Blacklist "Raw" "Proofs". (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Set Search Output Name Only. (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Redirect "/tmp/coq14243Gze" SearchPattern _. (* Finished transaction in 1.321 secs (0.416u,0.011s) (successful) *) (* also, prints out 17502 lines of identifiers *)
Time Redirect "/tmp/coq14243T9k" SearchAbout -"____". (* Finished transaction in 0.985 secs (0.384u,0.016s) (successful) *) (* also prints out 17502 lines of identifiers *)
Time Remove Search Blacklist "Raw" "Proofs". (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
Time Unset Search Output Name Only. (* Finished transaction in 0. secs (0.u,0.s) (successful) *)
(I thought Redirect
was supposed to write to a file instead of printing to output?)
(I thought Redirect was supposed to write to a file instead of printing to output?)
?! doesn't it? It does for me on 8.6...
Time Redirect "/tmp/coq14243Gze" SearchPattern _. ( Finished transaction in 1.321 secs (0.416u,0.011s) (successful) ) ( also, prints out 17502 lines of identifiers ) Time Redirect "/tmp/coq14243T9k" SearchAbout -"____". ( Finished transaction in 0.985 secs (0.384u,0.016s) (successful) ) ( also prints out 17502 lines of identifiers )
Hmm, still super long, then.
I think redirect is not working properly in 8.7, see coq/coq#6130 . It should be easy to fix.
Perhaps this is an instance of "doctor, it hurts when I poke myself". (This is in Coq 8.6)