Poor performances when typing in rectangle selection #58
Labels
No labels
Area-Accessibility
Area-Build
Area-CodeCompletion
Area-Document
Area-Documentation
Area-Editing
Area-Folding
Area-Highlighting
Area-i18n
Area-Indentation
Area-NetFx
Area-Rendering
Area-Search
Area-Snippets
dependencies
duplicate
Feedback Needed
help wanted
invalid
Issue-Bug
Issue-Discussion
Issue-Enhancement
Issue-Performance
Issue-Question
on-hold
Resolution-Answered
Resolution-By Design
Resolution-Duplicate
Resolution-Fixed
Resolution-Won't Fix
Up-for-Grabs
No milestone
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-icsharpcode/AvalonEdit#58
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
On a file with about 1000 lines of text and syntax highlighting turned on, making a rectangle selection with more ~15 lines makes editing inside the selection very slow, dropping to something like 1 character per second.
I am still noticing this with current versions of AvalonEdit. I even turned off syntax highlighting and collapsing and even so, when I have a decent size block selection and try to type sometimes it takes a second per character.
Anyone have any ideas about fixes or optimizations? We unfortunately have a lot of people doing block selecting in our application...
I have noticed that some of the things mentioned in #9 do help. Turning off space showing does make it a little faster, but we need spaces shown, and also it really seems to happen more with block select.
@siegfriedpammer could this be fixed by using
Document.BeginUpdate()andDocument.EndUpdate()Or are you doing this already?
Could you point me at the relevant code, so that I can maybe try a PR ...
I would be happy to take a look at this as well if someone could point me to the relevant area in the code. We finally were able to update our VS version so I can actually give fixing this a try!
Our users are literally copy/pasting in/out of WordPad or NP++ in order to do block selection and typing because that's faster than trying to do it in the editor.
@goswinr I'm looking at the code and they do seem to have that area of code wrapped with
using (textArea.Document.RunUpdate())(so it does begin/end update), so that's not going to change anything.I did some benchmark testing on my brand new and decently high-spec computer, timing this section of the code:
~100 lines took consistently 1.5-4 seconds
~500 lines took consistently almost a full minute
Looking a little deeper, the slowest part of
ReplaceSingleLineText()seems to be theDocument.Insert()andDocument.Replace()calls. To similar examples as before:~180 lines too about 22ms per call
~540 lines took about 125ms per call
So first off, even without too many lines, that's quite slow for an action that's done for each line. 22ms * 180 lines is about 4 seconds just for the
Insert()calls. That means 4+ seconds per character press if you're trying to type in just 180 lines. With 540 lines it took over a full minute, again meaning that if you're trying to type in a block selection, you have to wait over a minute per key press.I'm curious why the time in that function jumps so high. A 3x increase in lines consistently increased the call time by 5x, and that's nowhere near the max amount of lines our users would want to be able to select.
Just to add more as I debug, 90+% of the time is in
TextArea.OnDocumentChanged()and almost all of that is theselection.UpdateOnDocumentChange(e)line. So it's theUpdateOnDocumentChange()method ofRectangularSelection.I'm not sure why the selection needs to be updated after each line of a change, and not just at the end. I.e. it seems like this update should be deferred by some mechanism if the change is triggered by a rectangular selection action.
Just for testing I commented out the changed event call (TextDocument.cs around line 877), it didn't seem to have any changes to behavior (visually things still seem to update) but the 500 line change takes 1-1.5 seconds per character, an order of magnitude difference. 100 lines was still the slightest bit jumpy, but markedly better at around 0.2-0.25 seconds for per character.
Also, just a note, the debugging output to time things that I have been putting in for testing is actually slowing stuff down. With no debugging output, and only timing the whole change, it takes on average about 0.1 seconds per character press for 500 lines. But for the purpose of debugging, the overhead added should be relatively constant (make 2 DateTimes, subtract them, and log it to the console).
Ugh, well the side effect of not calling
Changed()around line 877 is that it doesn't update the caret for normal typing.@zaksmolen I could significantly improve the performance of typing in a rectangle selection by using TextArea.PreviewTextInput event , then doing the block edit myself via a Stringbuilder and then call doc.Replace only once. maybe something similar might help you. Changing the font or reducing the syntax highlighting might help too see https://github.com/icsharpcode/AvalonEdit/issues/252
I believe I have finally resolved this in pull request 269.