This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.
Development build #200508311800 of NetBeans 4.2 Windows XP, JDK 1.5.0_05 build #02 Description: ============ User must be extra patient when editing long XML based files. There is a certain usecase described below causing editor to hang for some time every two seconds and CPU consumption reaches ~100%. Steps to reproduce: =================== 1. Create new sample web application project. 2. Save attached HTML in the project and open it. 3. At last line 772 type </ and press & hold e.g. A key. 4. You should observe significant delays after a while occuring after every ~2 seconds.
Created attachment 24442 [details] HTML file reproducing the performance problem.
This is performance degradation issue.
As I have mentioned in Issue #55541, I cannot improve the find matching block mechanism much. The problem is caused by the missing end tag. If you write a tag then after each keystroke a matching tag is searched. Because of there isn't any matching endtag the entire document is searched which is time consuming especially for big files. What I can do is to filter out some of these keystrokes if they come very quickly. So the find of the matching block will be called for example after 500ms delay when no new keystroke comes. As soon as we have and implementation of DocumentModelProvider for HTML tags I can rewrite the matching to be based on the model. Then there will be no delays at all since I always know exact locations of all the tags.
Currently the SyntaxSupport.findMatchingBlock(...) is called synchronously from EDT on each keystroke and hence cause performance problems when the call takes longer time (HTML/JSP/XML - see described usecase). I am attaching a simple patch for editor/lib module which causes the SS.fmb() method to be called asynchronously after an amount of time (the same behaviour as when you change the carret offset in the editor). I am reassigning the issue to Mila Metelka for review of the patch (I am not sure whether the synchronous call is necessary by another part of editor code - from the user perspective everything works the same as before in java, htmls, ...). If the patch is OK please integrate or reassign back to me. Thanks.
I don't see any patch. Mila, do you know exactly what's the requested improvement? Tomasz or Marek, do you know whether the behavior has changed in any way in NetBeans 5.5? Thanks.
I understand the logic of not doing the complex computation synchronously. However IMHO just the re-posting later into event queue would not help as there would be the same amount of work to be performed. I've looked again into ExtCaret implementation and originally there was a timer for matching the braces with 100ms timeout but later there was a matchBraceUpdateSync added for key typed events. If XML would override the ExtCaret in the following way: public void requestMatchBraceUpdateSync() { matchBraceUpdateSync = false; } and create the overriden caret in XMLKit.createCaret() then this solution would imho fix the problem in most effective way.
Tomasz, can you please look at this? Thanks.
the issue is still reproducible
I used the hint from jlahoda to make calls to findMatchingBlock(), asynchronous and it seems to help. However a new thread is created each time the caret is moved and the threads work in parallel; when the user is typing fast the CPU is blocked. The solution could be to post the task to a custom RequestProcessor with capacity of one thread, probably with some timeout.
sorry, not jlahoda's, but mmetelka's hint
Notice that RP.Task is Cancellable. if you implement the runnable properly, you can easily push the interruption through the stack back to your code. Also, don't .post() the runnable, .schedule precreated Task, it would automatically cancel any pending (not yet running) requests so you won't end up with 10 of them in the RP queue.
OK, I'll modify ExtCaret to use the RP.Task. tslota do you plan to merge this fix into 5.5? I'm asking because cancelling of the task will interrupt the thread which is IMHO a bit sensitive and also the whole computation will now be done outside of the AWT - anyway I expect that no deadlocks or other problems should occur with changing this.
mmetelka: let's try it on a local build first, if the the improvement is very visible and we don't see any issues with it it should go to 'release55'.
Created attachment 33710 [details] Briefly tested diff of ExtCaret.java implementing RP.Task.
Found another sub-problem: there are multiple, concurrent threads of folding manager created when the user is typing the closing tag. mfukala is fixing it
Fixed. Editing attached HTML still feels somewhat sluggish, but the problem described was solved and it is much better now. See also issue 84598. Change log: Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java; /cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v <-- ExtCaret.java new revision: 1.39.34.2.2.2; previous revision: 1.39.34.2.2.1 done Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java; /cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v <-- HTMLKit.java new revision: 1.9.8.2.2.4; previous revision: 1.9.8.2.2.3 done
The fix will be ported to trunk as part of the merge of release55_dev.
Unfortunately this fix is causing a serious P1 issue #86661 so I have to rollback it both in release55_dev and release55. We may possibly leave it in the trunk for some time to see whether the fix of #85000 will possibly make any difference to the symptoms of #86661 but personally I don't think so.
Rollback in release55_dev: Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java; /cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v <-- ExtCaret.java new revision: 1.39.34.2.2.2.2.1; previous revision: 1.39.34.2.2.2 done Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java; /cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v <-- HTMLKit.java new revision: 1.9.8.2.2.4.2.1; previous revision: 1.9.8.2.2.4 Rollback in release55: Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java; /cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v <-- ExtCaret.java new revision: 1.39.34.2.2.3; previous revision: 1.39.34.2.2.2 done Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java; /cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v <-- HTMLKit.java new revision: 1.9.8.2.2.5; previous revision: 1.9.8.2.2.4
Rollback in trunk due to possible cause of issue #87598: Checking in editor/libsrc/org/netbeans/editor/ext/ExtCaret.java; /cvs/editor/libsrc/org/netbeans/editor/ext/ExtCaret.java,v <-- ExtCaret.java new revision: 1.46; previous revision: 1.45 done Checking in html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java; /cvs/html/editor/src/org/netbeans/modules/editor/html/HTMLKit.java,v <-- HTMLKit.java new revision: 1.17; previous revision: 1.16
I was hoping this issue could have been fixed by "lexerization" of the HTML editor, unfortunately it seems to have gotten worse. Also opening and scrolling attached file feels unacceptably sluggish, it wasn't an issue before. Upgrading to P2
I've profiled the HTML editor module and figured out that when scrolling more than 90% of CPU time is spent in the HTML.tagName() method
While HTML.tagName() is most expensive in the AWT thread, it is also worth to take a look at HTML.resolve(), which is a very expensive method in the Parser thread. The biggest source of load in HTML.tagName() is TokenSequence.movePrevious() - 84%.
Can you please attach the profiler results? It is not easy to determine what can be wrong without it.
Created attachment 44561 [details] Profiling results (root methods HTML.tagName() and HTML.resolve())
The first problem is cause by the error checking layer trying to check if an attribute or tag is deprecated. There is a call for each token and the call is extremely costly. Resolution: a.the method must be fastened + b.the highlight layer should be cached. Vito,is #b currently implemented? The second problem is that after some time when the edited document is modified the Schlieman parser is run and once the parse is done, an AST evaluator is called. The AST evaluation (HTML.resolve()) is very very slow and creates a huge number of new objects. The original design of this comes from Hanz, I'll try fix this by myself somehow or to reassign to him. Rassigning the issue to myself for now to address the problems.
#1 fixed Checking in HTML.java; /cvs/html/editor/src/org/netbeans/modules/html/editor/HTML.java,v <-- HTML.java new revision: 1.8; previous revision: 1.7 done
resolution of #2 should be based on changing the way how the parse tree is resolved. For those who are not familiar with the mechanism - the parse tree resolvation creates from the plain parse tree from parser an AST containing hierarchical information about tags nesting, evaluates which tags are unbalanced, empty etc. During this process the old tree stays untouched and a new one is created by modifying and cloning its nodes. All nodes, even those which stays untouched in the new tree, are cloned with all its children. This seems to be superfluous to me, supposing that noone ever changes the given parse tree, the untouched nodes can be referenced directly IMHO. I'll try to change it this way.
Tome, could be please so nice and try the attached patch for #2 with the profiler? I do not know what exactly you did in the editor when creating the cpu data so it will be more precise. Also please update to check fix of #1. Thank you!
Created attachment 44573 [details] The problem #2 fix attempt source patch
Created attachment 44575 [details] Profiling results after applying the patch
The patch helps a bit, but performance is still unacceptable. It improved greatly when I commented out the HTML.isDeprecatedTag() method.
I am sorry the previous fix was erroneous, this time it works (I checked it). So update uncomment isDeprecatedTag and enjoy :-) Checking in HTML.java; /cvs/html/editor/src/org/netbeans/modules/html/editor/HTML.java,v <-- HTML.java new revision: 1.9; previous revision: 1.8 done Though the fix should help a lot, there are some more findings: I tested it a little and find out that the problem is in the missing highlight layer chaching. The HTML.isDT() is called each time a token is going to repaint. So during scrolling of big html document it leads to large number of calls to this method without caching. Hanz still uses the old DrawLayers instead of the HiglightsLayer which is cached I belive. So either MyFirst/SecondDrawlayer from Schlieman needs to be cached or HighlightsLayer used.
After the last change the overall performance is already acceptable, following agreement with Marek I am leaving the issue open until #2 is also addressed.
I already commited the fix for #2 in the last commit. So closing this issue as fixed.