Bug 481156 - Inefficient algorithm in XMLModelParser slows down XML Editor
Summary: Inefficient algorithm in XMLModelParser slows down XML Editor
Status: NEW
Alias: None
Product: WTP Source Editing
Classification: WebTools
Component: wst.xml (show other bugs)
Version: 3.7   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: wst.xml CLA
QA Contact: Nick Sandonato CLA
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2015-10-30 17:53 EDT by Slava Kabanovich CLA
Modified: 2015-11-03 05:15 EST (History)
3 users (show)

See Also:


Attachments
Proposed patch (12.74 KB, patch)
2015-10-30 17:53 EDT, Slava Kabanovich CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Slava Kabanovich CLA 2015-10-30 17:53:23 EDT
Created attachment 257663 [details]
Proposed patch

In specific cases XMLModelParser can hang XML Editor and/or cause crash because of lack of memory. 
In many other cases, the slowing is not so dramatic, but still XMLModelParser causes a lot of unnecessary CPU and memory load.

This issue is not a duplicate of https://bugs.eclipse.org/bugs/show_bug.cgi?id=242802 because it can be reproduced with relatively small files (20Kb), while with large files (1Mb and more) other factors may contribute.

Test case:
1. Start with an xml
<a>
 <b>c</b>
</a>
open in the XML Editor.

2. Select and copy second line (with the end of line) and insert it in the beginning of second line to obtain
<a>
 <b>c</b>
 <b>c</b>
</a>

3. Repeat selectind and copying all '<b>c</b>' lines and inserting them in the beginning of second line.
In this way, file will contain 2, 4, 8, 16, 32, 64, etc. '<b>c</b>' lines.

4. When file reaches 256 lines start measuring time after insertion that XML Editor takes to respond to input again. On my computer, inserting 1024 lines to get 2048 lines took half a minute. After the next step, inserting 2048 lines, XML editor never recovered, Eclipse crashed with OutOfMemoryError. At that moment file was only 20 Kb.
Note that if the insertion is done right before closing tag </a> rather than before the list of <b> elements, it causes no problems.

5. Instead of measuring time one can put a breakpoint into XMLModelNotifierImpl.notifyDeferred() after 
int count = this.fEvents.size();
and look how much events were generated by the insertion.
I got the sequence: 13, 40, 142, 538, 2098, 8290, 32962, 131458, 525058, 2098690, 8391682, crash.


That is why it happens. XMLModelNotifierImpl inserts regions one by one in the order as they appear in text. When opening tag <b> is inserted as first child of <a></a>, all its existing children are moved from <a> to <b>. That is very nice if inserted text does not contain later closing tag </b>. When it contains it, all nodes that were (and should be) children of <a> are moved back from <b> to <a>. This algorithm produces a lot of computations and events. In many cases, XMLModelNotifierImpl saves UI from the tsunami of events, but actually it is a bit too late to try and reduce efficiently their amount when there should not be as many of them in the first place.

I attach the patch that solves the problem.
Comment 1 Nitin Dahyabhai CLA 2015-10-31 14:31:56 EDT
(In reply to Slava Kabanovich from comment #0)
> I attach the patch that solves the problem.

Slava, could you go ahead and sign the CLA (instruction are at http://wiki.eclipse.org/CLA) so we can apply this for Mars.2 after review?
Comment 2 Max Rydahl Andersen CLA 2015-11-03 05:15:33 EST
Nitin,

Slava works for Red Hat so he should be covered by Red Hat CLA.