user1168608
user1168608

Reputation: 618

Performance issue while loading huge table(SWT/JFace)

I have a JFace TableViewer (with approximately 1k rows) which is created in the following way:

TableViewer tableViewer = new TableViewer(composite, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.MULTI | SWT.VIRTUAL);

I have set the Content and Label Providers:

tableViewer.setContentProvider(new SampleTableContentProvider());
tableViewer.setLabelProvider(new SampleTableLabelProvider());
tableViewer.setInput(inputObject);
tableViewer.setComparator(sorter);

I am also Setting Images to two columns by overriding getImage(Object element, int colNumber) method.

It is taking a lot of time to load the table. How do i improve the Performance?

Upvotes: 3

Views: 1395

Answers (1)

Rüdiger Herrmann
Rüdiger Herrmann

Reputation: 21025

(Note that this might not necessarily answer the question, but the comment field does not have formatting and enough space.)

While the SWT Table and JFace TableViewer isn't best known for its performance, showing 1000 elements should not cause a performante hit.

The snippet below creates a (not even virtual) TableViewer with 5000 elements and does not take noticable time to render:

public class TableViewerPerformance {

  public static void main( String[] args ) {
    Display display = new Display();
    Shell shell = new Shell( display );
    shell.setLayout( new FillLayout() );
    TableViewer tableViewer = new TableViewer( shell, SWT.NONE );
    tableViewer.setLabelProvider( new LabelProvider() );
    tableViewer.setContentProvider( ArrayContentProvider.getInstance() );
    tableViewer.setInput( createModel() );
    shell.open();
    while( !shell.isDisposed() ) {
      if( !display.readAndDispatch() )
        display.sleep();
    }
    display.dispose();
  }

  private static Collection<Object> createModel() {
    Collection<Object> elements = new ArrayList<Object>();
    for( int i = 0; i < 5000; i++ ) {
      elements.add( new Object() );
    }
    return elements;
  }
}

If you use something like the above as the basis you can gradually add features from your application code and see when performance degrades.

Also here are some common things to look out for to improve the performance of TableViewers

  • try to use hash lookups. TableViewer#setUseHashlookup( true ) must be called before setting the viewers imput

  • try to make your table is VIRTUAL. A Virtual table does only create TableItems when they become visible. Thus when the table is initially shown there are 20 or so TableItems created (as many as you actually see) instead of 1000. Sorting is not affected, you can use TableViewer#setComparator() like without the VIRTUAL flag.

  • try to use ILazyContentProvider in combination with VIRTUAL. This requires to sort elements yourself. This means that instead of setting a comparator on the TableViewer you need to sort the model elements before they are returned by the content provider.

  • if you don't do that already, try to buffer images instead of creating them anew on each ILabelProvider#getImage() call

  • if it is your model that takes time to load, try to run this operation in a background thread. Thus the UI thread is not blocked and the application remains responsive.

Ultimately I recommend to use a profiler instead of guessing which part of the code is responsible for the bad performance.

Upvotes: 2

Related Questions