Bug 103436 - Performance of selection in a multi-select table
Summary: Performance of selection in a multi-select table
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.1   Edit
Hardware: PC Linux-GTK
: P3 normal (vote)
Target Milestone: 3.2 M1   Edit
Assignee: Billy Biggs CLA
QA Contact:
URL:
Whiteboard:
Keywords: performance
Depends on:
Blocks:
 
Reported: 2005-07-11 22:02 EDT by Klemen Zagar CLA
Modified: 2005-07-13 22:54 EDT (History)
1 user (show)

See Also:


Attachments
Patch to Table.java (1.52 KB, patch)
2005-07-11 22:43 EDT, Billy Biggs CLA
no flags Details | Diff
GTK+ test case (2.88 KB, text/plain)
2005-07-11 23:23 EDT, Billy Biggs CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Klemen Zagar CLA 2005-07-11 22:02:28 EDT
If a table has many elements (e.g., a virtual table with 100k entries), the
selection takes quite a lot of time to respond to a mouse click (~1 second). I
have investigated the bottleneck, and found it to be in function
gtk_tree_selection_selected_foreach of class OS (line 6245).

In my particular scenario (Linux FC2, 1.6GHz Centrino, 100k entires, table
styles SWT.MULTI and SWT.VIRTUAL), this function gets called three times per
selection, each time requiring some 0.3 seconds (with some 70ms between two
consecutive calls). The calls are due to a call to Table.getSelection().

The Table.getSelection() also creates an integer array with the same number of
elements as there are items in the table. In itself, this doesn't take much
time, but may consume a lot of memory (e.g., 20 mio entries).
 
Is there a way to optimize this interaction with GTK? I have a feeling that
performance with Eclipse 3.0 was better in this regard (but I haven't
quantitatively measured this -- it's just a vague recollection). Perhaps only an
array of selected indices could be retrieved from the GTK?
Comment 1 Billy Biggs CLA 2005-07-11 22:12:46 EDT
Thanks for the detailed analysis of what's going on, I'll see what's up.
Comment 2 Billy Biggs CLA 2005-07-11 22:39:31 EDT
Here is the test app I'm using.  Seems much slower than I would expect.

public static void main(String[] args){
	Display display = new Display ();
	Shell shell = new Shell(display);
	shell.setLayout(new FillLayout());
	final Table table = new Table(shell, SWT.MULTI | SWT.VIRTUAL);
	table.addListener(SWT.SetData, new Listener() {
		public void handleEvent(Event event) {
			TableItem item = (TableItem) event.item;
			item.setText("Item");
		}
	});
	table.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			long before, after;
			before = System.currentTimeMillis();
			table.getSelection();
			after = System.currentTimeMillis();
			System.out.println("Time: " + (after-before) + " ms.");				
		}
	});
	table.setItemCount(100000);
	shell.open();
	while (!shell.isDisposed ())
		if (!display.readAndDispatch ()) display.sleep ();
	display.dispose();
}
Comment 3 Billy Biggs CLA 2005-07-11 22:43:02 EDT
Created attachment 24588 [details]
Patch to Table.java

Here is a patch that makes the time much more reasonable on my machine.  The
fix was to use gtk_tree_selection_get_selected_rows() instead of
gtk_tree_selection_selected_foreach().	It is not yet clear to me why there is
such a large difference.

I will clean the patch up a bit before I commit it, but I think we should also
determine what was wrong with using the foreach function.
Comment 4 Billy Biggs CLA 2005-07-11 22:44:57 EDT
Using gtk_tree_selection_get_selected_rows() is also better since we don't need
to allocate the big array.  The function is new for GTK+ 2.2, but we already
depend on GTK+ > 2.2 in other places so it's no longer an issue.  This is
probably why the foreach was being used in the first place.
Comment 5 Billy Biggs CLA 2005-07-11 23:23:03 EDT
Created attachment 24591 [details]
GTK+ test case

For reference, here's a small GTK+ test app.  Using foreach is at least 10x
slower than get_selected_rows.	AFAICT, the difference is in maintaining the
iters for the callback, as this needs to query the model.   I'm not convinced
there's a GTK+ bug here, but the large difference in performance is unexpected.
Comment 6 Billy Biggs CLA 2005-07-12 21:30:16 EDT
Fixed > 20050712 in SWT for Table, Tree, and List.

Kristian Rietveld has fixed the upstream problem in GTK+ CVS, so as of GTK+
2.8.0 the performance of both functions will be the same.  The extra cost was
from maintaining the iters, and it was fixed by only obtaining an iter for the
selected items.
Comment 7 Billy Biggs CLA 2005-07-13 22:54:15 EDT
For reference, here was the change in GTK+:

2005-07-13  Kristian Rietveld  <kris@gtk.org>

	* gtk/gtktreeselection.c (gtk_tree_selection_selected_foreach): quit
	maintaining the iter on every iteration, only get the iter when
	we are about to call the foreach_func. Gives us a 10x speedup,
	since maintaining iters is a lot more expensive than maintaining
	paths. We lose a bit of sanity checking though. Thanks go to
	Billy Biggs for pointing this out.