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.
While editing large documents, inserting line break is slow at the beginning of the document. The problem seems to lay in DocumentLine.equals() which is too slow in the implementation internals. See the attached StackTrace. Reassign to openide/text if applicable
Created attachment 4656 [details] Thread dump during the pause, only relevant thread
If a break is entered at the beggining of a file, all (N) lines are moved, for all such lines a lineMove is fired which causes comparison of all the lines with *all* registered lines (M) in the same document (because all the DocumentLines from a single document have the same hashCode()), i.e. NxM*equals(). During the subsequent equals() calls, each of the M registered lines is asked for their lineNumber which is computed by a complex logic in both openide/text and editor N times. Now the raw numbers: For a 1000-line file and a standard M=1, it is hardly noticeable. For a 1000-line file unsucessfully compiled with ~30 error annotations (e.g. a wrong closing brace), it takes about 1.5s to insert a line break on my machine. We've got reports with way longer times.
cc:ing Peter, owner of openide/text
It may be the best to not use LineListener at all and let the Line.Set listen on the Document itself.
Although that will probably not help too much for elimination of this issue I would like to switch to have permanent LineElements in 3.4. The editor currently uses SyntaxMarks to store both the lexer info and the line number. The syntax marks are constructed roughly at every 100th character (rouhly one mark per 5 lines). The line elements are created lazily on demand. When we move to use the lexer module the syntax marks will no longer be used so the only sense would be the line orientation. Although the editor has specialized methods to handle line-oriented operations all the "external" modules use the Swing API to get rid of dependency on the editor. The typical scenario of use is I guess the following: line-root-element.find-line-element-index(position.getOffset()); This leads to use of the binary search to find the right line element for the given offset. This will not be improved even in the new implementation. What can be improved is the fact that with the current implementation there is a cache for holding starting and ending offset of the particular line. The line boundaries are computed when the line is loaded into the cache. Normally about 98% of requests hits the cache but if the requests come from the different locations in the document the cache is not efficient enough.Altough the permanent line elements will use more memory the line boundaries will be known from the elements directly so there should be some performance improvement by using this approach.
Fixed in [main-trunk] Fix: openide/../text/CloneableEditorSupport.java [1.54] DocumentLine.java [1.43] EditorSupportLineSet.java [1.29] Line.java [1.19] LineListener.java [1.9] Please revise the fix, if you find a time. Thanks.
Great, way better
There was a regression by the above fix, see #21086.
Created attachment 5114 [details] Diff of patch+regression fix for orion_fcs branch
Created attachment 5115 [details] Patch (put in orion_fcs lib/patches dir) to try out.
Please, review and approve for [orion_fcs] branch integration.
Approved.
Resolved for 3.4.x or earlier, no new info since then -> closing.