-
-
Notifications
You must be signed in to change notification settings - Fork 219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
improve performance of rangeForDefun (cause of repl slowness) #942 #1237
Conversation
5e4f02b
to
2a7438f
Compare
I've rebased this PR to current dev, so that it VSIX for testing has those 2.0.205 changes included. |
Awesome. This performance bottleneck is causing Calva to feel quite broken when I run in to it. Can you add some pointers to what people should test when they get hold of the VSIX to the PR description? From the top of my mind:
I am probably missing things, am in a bit of a hurry... |
For the debugger, testing that breakpoints are found and that stepping works correctly should suffice. |
Nicely spot @bpringe, I never noticed that these unbalanced parentheses gets highlighted in red, so I wasn't really missing this behavior. @PEZ I've debugged current endRange = endCursor.rangeForDefun(endOffset, false),
rangeStart = startRange[0],
rangeEnd = endRange[1]; // <-- NPE here as endRange is null A simple fix might be adding two additional rangeForDefun(offset: number, commentCreatesTopLevel = true): [number, number] {
const cursor = this.doc.getTokenCursor(offset);
let lastCandidateRange: [number, number] = cursor.rangeForCurrentForm(offset);
while (cursor.forwardList() && cursor.upList()) {
const commentCursor = cursor.clone();
commentCursor.backwardDownList();
if (!commentCreatesTopLevel || commentCursor.getToken().raw !== ')' || commentCursor.getFunctionName() !== 'comment') {
const currentFormRange = cursor.rangeForCurrentForm(cursor.offsetStart);
if (currentFormRange !== undefined) {
lastCandidateRange = currentFormRange;
}
}
}
return (lastCandidateRange !== undefined)
? lastCandidateRange
: [offset, offset];
} This alone helps in situation where the unbalanced bracket is the last form in editor viewport that gets examined in I suspect that it might somehow be related to yet another changed behavior: (ns a
(:require [clojure.string :as s]))
(defn foo []
(let [bar 1]
"bar")) ) ;; <- last paren on this line is unbalanced
(println (s/upper-case "test output"))
| When I evaluate this in old Unfortunately the whole logic in |
Great find, @bpringe, and awesome investigation, @brdloush! As for new evaluation behaviour with unbalanced parens, I don't worry about that. Unbalance is unbalance. 😀 I'm thinking that instead of fixing the call site with that highlight miss, is it hard to fix the defun method to keep the behaviour it used to have in respect to what is returned in this particular case? I'm far afk, so can't check myself right now. |
OK. So rereading @brdloush 's comment with a desktop browser, I see there is a suggestion to keep the old Testing this I notice that clj-kondo has a check for unbalance that is better than Calva's. Hmmm... |
@PEZ I have one more observation. Consider this code |(ns a
(:require [clojure.string :as s])) ;; <-- forwardUpSexp normally jumps after this paren, but not with unbalanced paren..
(defn foo []
(let [bar 1]
"bar")) ) ;; <-- this last paren is ubalanced - forwardUpSexp actually ends up here
:last-form If there's this unbalanced paren on "bar" line and I have a cursor at the very beginning ( I believe this is a problem for that @PEZ what do you think about that |
@brdloush I think it is worth a try to fix the case you are pointing at. That said, it remains hard to define the ”correct” behaviour in the face of unbalance. Let's not do it in this PR. Thinking about the highlight problem I started to think it makes sense that when we don't find a top level form, we return |
@PEZ your commit fixes this case but as mentioned, not the one when there are more forms after the imbalance: |
@brdloush is the case that is not fixed caused by this PR or something we already have in the released version? |
The highlighting itself works ok in released version. As I wrote in my previous comment, I think that the fact that highlighting is broken in our new branch is related to the fact that we now rely on Even in released version, |
Ah, I'm starting to get it. =) |
Pushed a fix for |
👍 It's behaving very well now including the highlighting 👏 I'll install the VSIX later today or tomorrow and try to re-test everything more thoroughly. @bpringe can you perhaps re-test your scenarios as well? |
I've been pretty busy but I'll try to test this in the next couple of days, if it's still needed. |
Thanks for helping with analysing this problem and persisting with analysing it down to the root causes, @brdloush! I think that we managed to navigate this such that the right fixes where applied and also the tests improved a lot. Let's deal with any regressions and room for improvements in future PRs. |
Awesome, looking forward to the next release 👏 |
What has Changed?
rangeForDefun
got rewritten so that it no longer needs to navigate from the very beginning of the document (which caused slowness when appending to repl window)rangeForDefun
(as there weren't any :-))Greatly improves #942. Before the fix, outputting become sluggish at 6k lines and was nearly unusable at just 10k (freezes for 30-60s). Now even 100k lines is bearable : execution of repl expression takes about 5 seconds.
My Calva PR Checklist
I have:
dev
branch. (Or have specific reasons to target some other branch.)published
. (Sorry for the nagging.)[Unreleased]
entry inCHANGELOG.md
, linking the issue(s) that the PR is addressing.ci/circleci: build
test. NB: You need to sign in/up at Circle CI to find the Artifacts tab.[ ] If I am fixing the issue, I have used GitHub's fixes/closes syntax[ ] Created the issue I am fixing/addressing, if it was not present.The Calva Team PR Checklist:
Before merging we (at least one of us) have:
dev
branch (unless reasons).Ping @PEZ, @bpringe