Bug 259141 - Tree.getSelection() is extremely slow with SWT.VIRTUAL and SWT.MULTI
Summary: Tree.getSelection() is extremely slow with SWT.VIRTUAL and SWT.MULTI
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.4.2   Edit
Hardware: PC Windows XP
: P3 normal with 3 votes (vote)
Target Milestone: 3.8.2   Edit
Assignee: Carolyn MacLeod CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 310260 (view as bug list)
Depends on:
Blocks: 289848 327214
  Show dependency tree
 
Reported: 2008-12-17 12:13 EST by Nicolas Bros CLA
Modified: 2014-08-07 04:41 EDT (History)
18 users (show)

See Also:
Silenio_Quarti: review+


Attachments
Code snippet which exhibits the problem (3.49 KB, text/plain)
2008-12-17 12:13 EST, Nicolas Bros CLA
no flags Details
workaround (4.42 KB, application/octet-stream)
2010-10-21 05:42 EDT, Nicolas Bros CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Nicolas Bros CLA 2008-12-17 12:13:42 EST
Created attachment 120727 [details]
Code snippet which exhibits the problem

Build ID: M20080911-1700

I was trying to use a TreeViewer with the SWT.VIRTUAL style, to display a model with many (several thousand) elements.

When the Tree is given the SWT.SINGLE style, it performs fast. But when the SWT.MULTI style is used, the virtual TreeViewer becomes unbearably slow.

I pinpointed it (with the help of TPTP) to the Tree.getSelection() method, which is called by TreeViewer.replace(..) to initialize the elements when they become visible.

It looks like the getSelection method is O(n), n being the number of elements in the tree.


I attached a self-contained code snippet which exhibits the problem.
Comment 1 Felipe Heidrich CLA 2009-01-05 12:35:28 EST
Steve, is there anything you can do to improve this ?

I wrote a testcase (no jface) if you interested.
Comment 2 Felipe Heidrich CLA 2009-01-05 16:00:55 EST
Hit F1 to run the benchmark

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setLayout(new FillLayout());
	final Tree tree = new Tree(shell, SWT.VIRTUAL | SWT.MULTI);
	tree.setItemCount(10);
	tree.addListener(SWT.SetData, new Listener() {
		public void handleEvent(Event event) {
			TreeItem item = (TreeItem)event.item;
			TreeItem parentItem = item.getParentItem();
			if (parentItem == null) {
				item.setText("node "+tree.indexOf(item));
				item.setItemCount(1000);
			} else {
				item.setText(parentItem.getText()+" - "+parentItem.indexOf(item));
			}				
		}
	});
	
	display.addFilter(SWT.KeyDown, new Listener() {
		public void handleEvent(Event e) {
			if (e.keyCode != SWT.F1) return;
			System.out.println("Start..");
			long time= System.currentTimeMillis();
			for (int i = 0; i < 200; i++) {
				tree.getSelection();
//					tree.getSelectionCount();
			} 
			time = System.currentTimeMillis() - time;
			System.out.println("time " + time + " (ms)");
		}
	});
	shell.pack();
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}
Comment 3 Shami Willms CLA 2009-01-13 16:17:09 EST
I'm having the same problem because instead of following the lazy loading, it is loading not only all of the objects at each level that is expanded, but also the text at those levels.

Windows is much slower than unix, but it does not keep with lazy loading on either platforms.

I have a tree that has a depth of 4 and the 4th level has a large amount of items ~7000, and when I use setSelection, it takes 9-10 minutes to load on windows but only 15-20 seconds on linux.

I would like both of these to be less than a second by keeping everything lazy loaded, but am at a loss as to how to proceed.

Any help with this bug would be hugely appreciated.
Comment 4 Shami Willms CLA 2009-01-13 17:27:08 EST
I actually did not read this bug 100% correctly, I get the slowdown with setSelection()...not getSelection(), where it does not use lazy loading anymore with the VIRTUAL flag and a lazy content provider (with JFace)...but maybe they are related.
Comment 5 Nicolas Bros CLA 2009-08-17 04:21:41 EDT
Has anyone found a workaround for this bug?
It really makes it impossible to use lazy loading in my usecase.
Comment 6 Felipe Heidrich CLA 2010-04-23 08:54:25 EDT
*** Bug 310260 has been marked as a duplicate of this bug. ***
Comment 7 Derek Foster CLA 2010-04-23 19:42:00 EDT
Note that the above-mentioned duplicate bug (Bug 310260) goes into some detail as to what exactly is causing the slowdown, and also links to two other websites that discuss related issues and possible solutions.
Comment 8 Krzysztof Daniel CLA 2010-07-12 07:18:59 EDT
I have run the benchmark. It takes up to 5 seconds. But if I replace MULTI with SINGLE, it ends in no time (0ms).
Comment 9 Nicolas Bros CLA 2010-10-21 05:42:38 EDT
Created attachment 181374 [details]
workaround

I have found a workaround. This involves subclassing the Tree, responding to clicks in the tree (handling Ctrl and Shift selections), caching the selection, and returning the cached selection in getSelection().
Comment 10 Kay Kasemir CLA 2011-07-14 01:45:29 EDT
While originally reported for Eclipse 3.4 and Windows XP, the problem persists for  Eclipse 3.6.2 and Windows 7.

Thank you very much for your workaround, which helps under 3.6.2 and Windows 7 as well.
Comment 11 Steven Darnell CLA 2012-02-16 18:38:46 EST
My RCP application has a view that uses a CheckboxTreeViewer to select and control the display of objects in a document. It is common for the tree to contain hundreds of nodes and the tree must be refreshed when nodes are added, edited, or removed or when the focus changes to another document. Refreshes take 5-15 sec (or worse on slow computers), resulting in a very frustrating user experience.

Bug 327214 best explains the symptom observed in my application and Bug 310260 (closed as duplicate) seems to provide the best diagnosis of the root problem, but all roads lead to this bug. That is why I am posting my comments here.

The conversation has stalled with regards to fixing the underlying inefficiencies causing this bug. In my case, the workaround does not really help. How do we move forward from here?
Comment 12 Felipe Heidrich CLA 2012-02-21 10:54:32 EST
I see no alternative but changing the Tree control to store the selection in java instead of using native state.

As a general rule in SWT, we do not duplicate in java a state that is already maintain in the OS. But in this case the inefficiency to retrieve the selection state back from the OS is a good reason, in my opinion, to break this rule.
Comment 13 Steven Darnell CLA 2012-02-21 17:46:15 EST
@Felipe I am willing to assist with testing.
Comment 14 Steven Darnell CLA 2012-03-19 15:54:22 EDT
@Felipe Is it possible for this fix to make the Juno RC1 milestone? If not, what resources would be needed to commit a fix in time for the June release?
Comment 15 Steven Darnell CLA 2012-05-19 01:58:11 EDT
@Felipe Is it possible to address this bug for the 3.8.0 release next month? This is a continuing problem in my RCP app. I am willing to assist with testing.
Comment 16 Pawel Piech CLA 2012-08-02 13:20:11 EDT
CQ:WIND00367075
Comment 17 Dani Megert CLA 2012-08-07 04:50:04 EDT
Silenio, this heavily impacts the Debug views. Can SWT please take a look and assess whether a fix is possible for 4.3? Thanks.
Comment 18 Silenio Quarti CLA 2012-08-08 14:54:12 EDT
Carolyn and I to investigate when she is back from vacation.
Comment 19 Pawel Piech CLA 2012-10-12 09:44:44 EDT
Is this defect something that we may expect to see addressed in 4.3?  
If not, I'll pursue to use the workaround in debug.  In our product, we have been testing the workaround from comment #9 for the last couple of months with good results.
Comment 20 Carolyn MacLeod CLA 2012-10-16 16:36:24 EDT
We noticed that sub nodes of a collapsed branch cannot be selected, so we released a patch that doesn't do the recursion if the branch is not expanded.

This fixes the snippets in comment 0 and comment 2 (i.e. reduces the time to almost 0), but we were unable to test any CDT arrays mentioned in dup bug 310260.

Released to master:
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/commit/?id=33011ccbbc0b6a948bfc91856458fefc7ae32f4e

Please try this in a nightly build > 20121016 (assuming the nightly build is ok), or in an integration build > 20121023.

Let us know if this works for you.
Comment 21 Steven Darnell CLA 2012-10-22 22:14:57 EDT
I do not see a change in behavior when using Attachment 211148 [details] in Bug 327214 with swt-N20121022-1000-win32-win32-x86 (Windows 7 x64, Java 6u37 x86, SWT 32-bit). The initial tree drawings take ~8 sec and the refreshes take even longer.
Comment 22 Carolyn MacLeod CLA 2012-10-23 12:58:32 EDT
I have reassigned Bug 327214 to JFace, because that problem is in JFace's CheckboxTreeViewer.

It would be great if someone (Pawel? Dani?) could say whether the fix we released in comment 20 improves the Debug views.
Comment 23 Pawel Piech CLA 2012-10-23 13:02:08 EDT
(In reply to comment #22)
> It would be great if someone (Pawel? Dani?) could say whether the fix we
> released in comment 20 improves the Debug views.

Sorry for the delay.  I'll confirm the fix later today or tomorrow (need a Windows box).
Comment 24 Pawel Piech CLA 2012-10-30 19:04:09 EDT
(In reply to comment #23)
> Sorry for the delay.  I'll confirm the fix later today or tomorrow (need a
> Windows box).

I finally got a chance to verify this fix with CDT.  The fix works, you can close the bug as far as I'm concerned.  Thank You!
Comment 25 Steven Darnell CLA 2012-10-30 19:08:22 EDT
Before closing the bug, I request that this fix be ported to both the 3.8 and 4.2 maintenance branches. The API has not changed and the fix provides a noticeable SWT Tree improvement. Thanks!
Comment 26 Dani Megert CLA 2012-10-31 03:32:34 EDT
(In reply to comment #25)
> Before closing the bug, I request that this fix be ported to both the 3.8
> and 4.2 maintenance branches. The API has not changed and the fix provides a
> noticeable SWT Tree improvement. Thanks!

+1.
Comment 27 Silenio Quarti CLA 2012-11-01 10:15:15 EDT
+1 to back port it to 3.8.2 and 4.2.1