Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 357201

Summary: Building resources with a lot of linking errors is very slow
Product: [Modeling] TMF Reporter: Lieven Lemiengre <lieven.lemiengre>
Component: XtextAssignee: Project Inbox <tmf.xtext-inbox>
Status: NEW --- QA Contact:
Severity: normal    
Priority: P3 CC: knut.wannheden, mail, mark.g.j.christiaens, mkomor, sebastian.zarnekow, sven.efftinge
Version: unspecifiedFlags: sven.efftinge: juno+
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:

Description Lieven Lemiengre CLA 2011-09-09 04:22:01 EDT
Build Identifier: 

When a resource has a lot of linking errors (>> 100) linking becomes very slow. The problem is caused by the datastructure that stores errors and warnings, an EList. In the methods “LazyLinkingResource. createAndAddDiagnostic” and “LazyLinkingResource. removeDiagnostic” errors are continuously being added and removed using the methods List.contains(Object), List.remove(Object). Both methods are O(N), if this datastructure was a Set these operations would run in constant time.
Since “EList<Diagnostic> getErrors();” and “EList<Diagnostic> getWarnings();” are defined on Resource (a part of EMF) I don’t know if this can be changed?

An alternative solution could be to limit the amount of errors and warnings per Resource. JDT limits the maximum number of problems per compilation unit as well. I think this is because starting eclipse becomes very slow when there are many problems in the workspace.


Reproducible: Always
Comment 1 Sebastian Zarnekow CLA 2011-09-22 14:10:42 EDT
I think it wouldn't hurt to use a second Set of diagnostics (both errors and warnings) or to override getErrors / getWarnings and use a custom implementation that provides better runtime characteristics than the default list implementation.

Should not be a big deal to implement.
Comment 2 Knut Wannheden CLA 2011-11-14 09:08:24 EST
One advantage of an auxiliary data structure: #removeDiagnostic() wouldn't have to call #createDiagnosticMessage(). It could use the Triple<EObject, EReference, INode> as the key. This should then be marginally faster as also the Diagnostic wouldn't need to be created if the issue didn't already exist (which should be the normal case).

Additionally this could solve potential problems if a customized ILinkingDiagnosticMessageProvider returns different messages based on some external context. Imaginary use case: The error message could be localized in different languages.