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.

Bug 220275 - DefaultCssEditorModule.getFoldsNodeVisitor() performance issue
Summary: DefaultCssEditorModule.getFoldsNodeVisitor() performance issue
Status: RESOLVED FIXED
Alias: None
Product: web
Classification: Unclassified
Component: CSS Editor (show other bugs)
Version: 7.3
Hardware: All All
: P3 normal (vote)
Assignee: Marek Fukala
URL:
Keywords: PERFORMANCE
: 220282 221476 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-10-17 12:38 UTC by Exceptions Reporter
Modified: 2012-11-30 02:45 UTC (History)
4 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter: 193662


Attachments
nps snapshot (18.41 KB, application/nps)
2012-10-17 12:38 UTC, Exceptions Reporter
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Exceptions Reporter 2012-10-17 12:38:50 UTC
This bug was originally marked as duplicate of bug 180230, that is already resolved. This bug is still valid, so this seems to be another bug, but it might be related.

Build: NetBeans IDE 7.3 Beta (Build 201210011125)
VM: Java HotSpot(TM) Client VM, 20.10-b01, Java(TM) SE Runtime Environment, 1.6.0_35-b10
OS: Windows XP
Maximum slowness yet reported was 4718 ms, average is 4718
Comment 1 Exceptions Reporter 2012-10-17 12:38:53 UTC
Created attachment 126075 [details]
nps snapshot
Comment 2 Milutin Kristofic 2012-10-17 14:31:36 UTC
*** Bug 220282 has been marked as a duplicate of this bug. ***
Comment 3 Svata Dedic 2012-10-17 14:53:49 UTC
There are two sources of low performance: CSL API might eventually use a copy of the document and do not invoke scan() under read lock.

The most effective fix, I think is in CSS - the getFoldsNodeVisitor uses LexerUtils.getLineOffset() to compute line number (line index), and the getLineOffset() reads the text from the start up to the passed offset. So if the source text rules are processed sequentially from the start to the end, this algorithm's complexity is not very good (seems like O(docSize ^ 2), sort of - not every char is a rule start.

Consider one of the following
a/ cache last visited Node's discovered line number in the Visitor instance. Each subsequent Node (assuming its offsets are higher than the predecessor) may start from the last Node's offset and only read the remainder of the text. Complexity is O(docSize).

b/ the snaphost is likely to contain an already opened Document instance (folding is only applied on documents opened in an editor). org.netbeans.editor.Utilities.getLineOffset() could be eventually called to compute the line # in a more effective way (using internal document Elements tree).
Comment 4 Marek Fukala 2012-10-17 15:24:09 UTC
(In reply to comment #3)
> There are two sources of low performance: CSL API might eventually use a copy
> of the document and do not invoke scan() under read lock.
> 
> The most effective fix, I think is in CSS - the getFoldsNodeVisitor uses
> LexerUtils.getLineOffset() to compute line number (line index), and the
> getLineOffset() reads the text from the start up to the passed offset. So if
> the source text rules are processed sequentially from the start to the end,
> this algorithm's complexity is not very good (seems like O(docSize ^ 2), sort
> of - not every char is a rule start.
> 
> Consider one of the following
> a/ cache last visited Node's discovered line number in the Visitor instance.
> Each subsequent Node (assuming its offsets are higher than the predecessor) may
> start from the last Node's offset and only read the remainder of the text.
> Complexity is O(docSize).

I think I'll create some kind of LinesResolver(CharSequence text) which creates and caches the all lines offsets so then lineResolver.getLine(int offset) will do just a binary search over the computed lines ranges.

> 
> b/ the snaphost is likely to contain an already opened Document instance
> (folding is only applied on documents opened in an editor).
> org.netbeans.editor.Utilities.getLineOffset() could be eventually called to
> compute the line # in a more effective way (using internal document Elements
> tree).

The document would have to be locked which is IMO not what is desired. If not locked then some modifications may happen and likely cause some BLEs.

Thanks Svato for the detailed evaluation. Next time, just reassign and say "css is bad and slow" and I'll fix - I do not want to loose too much of your time.
Comment 5 Svata Dedic 2012-10-17 15:27:12 UTC
Sorry ;) we were debating here with Milutin, what is the more appropriate fix - and whether it can be fixed in CSS at all. Better invest some time than to play bugzilla ping-pong :)
Comment 6 Marek Fukala 2012-10-17 15:50:18 UTC
:-) Thanks
Comment 7 Marek Fukala 2012-11-07 15:57:41 UTC
*** Bug 221476 has been marked as a duplicate of this bug. ***
Comment 8 Marek Fukala 2012-11-29 14:45:15 UTC
fixed in web-main#465762130765 by adding web.common.api.Lines which computes all lines for given CharSequence and then uses binary search for offset-> line index computation.
Comment 9 Quality Engineering 2012-11-30 02:45:34 UTC
Integrated into 'main-golden', will be available in build *201211300001* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/465762130765
User: Marek Fukala <mfukala@netbeans.org>
Log: #220275 - DefaultCssEditorModule.getFoldsNodeVisitor() performance issue