Community
Participate
Working Groups
EG (2/28/01 8:44:40 PM) building a project with many errors (> 1000) takes several minutes due to the bad task list update performance. This problem is severe, when self hosting you can easily create a workbench with many errors. NOTES: NE (3/5/01 6:08:45 PM) Problem is that TableViewer updates are O(N), resulting in O(N^2) performance for N marker additions. Should optimize TableViewer. In the meantime, try changing TaskListContentProvider.processDelta() to: /** * Process a resource delta. Updates the TaskList viewer with any * relevant marker changes. */ protected void processDelta(IResourceDelta delta) { //gather all marker changes from the delta List additions = new ArrayList(); List removals = new ArrayList(); List changes = new ArrayList(); getMarkerDeltas(delta, additions, removals, changes); //update the viewer based on the marker changes. if (removals.size() + additions.size() + changes.size() > 0) { // Just do a complete refresh for now if there are any changes to markers. fViewer.refresh(); } } EG (3/6/01 7:38:46 PM) It is only a marginal improvement. Without the patch 35s with the patch 30s. My test case is to load JavaUI Plugin project into an empty workspace and build. NE (03/06/01 3:14:07 PM) Did some timings on a text resource with 1000 tasks, in VA/Java. Full refresh took ~25 seconds. getSortedChildren(getRoot): 6025ms For an item at the start, the timings were: TableViewer.doUpdateItem(widget, element, true): 21.4 ms - just getting text and image from label provider, without setText(), getImage() or setImage(): 0.9ms - difference: 20.5ms For an item at the end, the timings were: Table.getColumnCount(): 0.5ms Table.indexOf(TableItem): 0.5ms TableItem.setText(column, text): 3.4ms TableItem.setImage(column, image): 1.9ms TableViewer.doUpdateItem(widget, element, true): 28.1ms - just getting text and image from label provider, without setText(), getImage() or setImage(): 6.9ms - difference: 21.2ms The reason getText() and getImage() take longer for the item at the end is that MarkerManager.findMarkerInfo() is O(N) in the number of markers on a resource. See 1GA6OQT: ITPCORE:WIN2000 - Marker access performance can be improved But there's still ~20ms per item accounted for just in setting the text and image on the TableItem, which accounts for ~20 seconds of the above 25, just in talking to SWT. Most performance problems in the task view will have to be addressed by improving incremental updates in TableViewer, where there is a lot of room for improvement. However, basic refresh, e.g. when toggling filters, will still take a long time, unless major improvements are made to SWT. It may not even be possible due to OS widget performance. As an example of what optimizations are possible in SWT, I tried optimizing TableItem.setText(String[]) and using it in doUpdateItem(). It improved the time for doUpdateItem() from 28ms to 17.5ms. But this is still slow when there are many items. Even basic redrawing of the Table widget a few seconds when there are this many entries. SN (3/7/01 10:51:50 AM) Here is the code for TableViewer.doUpdateItem (): protected void doUpdateItem(Widget widget, Object element, boolean fullMap) { if (widget instanceof TableItem) { TableItem item = (TableItem) widget; // remember element we are showing if (fullMap) { associate(element, item); } else { item.setData(element); mapElement(element, item); } IBaseLabelProvider prov = getLabelProvider(); ITableLabelProvider tprov = null; ILabelProvider lprov = null; if (prov instanceof ITableLabelProvider) { tprov = (ITableLabelProvider) prov; } else { lprov = (ILabelProvider) prov; } int columnCount = table.getColumnCount(); String[] texts = new String[columnCount]; TableItem ti = (TableItem) item; for (int column = 0; column < columnCount; column++) { // Similar code in TableTreeViewer.doUpdateItem() String text = ""; Image image = null; if (tprov != null) { text = tprov.getColumnText(element, column); image = tprov.getColumnImage(element, column); } else { if (column == 0) { text = lprov.getText(element); image = lprov.getImage(element); } } texts[column] = text; // Apparently a problem to setImage to null if already null if (image != null || ti.getImage(column) != null) { ti.setImage(column, image); } } ti.setText(texts); } } SN (3/7/01 10:52:28 AM) Here is a benchmark based on the above code: import com.ibm.swt.*; import com.ibm.swt.widgets.*; import com.ibm.swt.graphics.*; import java.io.*; public class PR_1G9VFMK { public static void main(String[] args){ /* Set up */ int rows = 1000, columns = 4; Display display = new Display (); Shell shell = new Shell(); Table table = new Table(shell, SWT.NULL); table.setHeaderVisible (true); table.setBounds (10, 10, 400, 200); shell.open(); for(int i = 0; i < columns; i++){ TableColumn column = new TableColumn(table, 0); column.setWidth (64); } TableItem [] items = new TableItem [rows]; for(int i = 0; i < rows; i++){ items [i] = new TableItem(table, SWT.NULL); } Image image = new Image (display, 16, 16); GC gc = new GC (image); gc.setBackground (display.getSystemColor (SWT.COLOR_RED)); gc.fillRectangle (image.getBounds ()); gc.dispose (); String text = "Hello"; /* Benchmark */ long start_time = System.currentTimeMillis(); for(int x = 0; x < rows; x++){ Widget widget = items [x]; if (widget instanceof TableItem) { TableItem item = (TableItem) widget; // // remember element we are showing // if (fullMap) { // associate(element, item); // } else { // item.setData(element); // mapElement(element, item); // } // // IBaseLabelProvider prov = getLabelProvider(); // ITableLabelProvider tprov = null; // ILabelProvider lprov = null; // if (prov instanceof ITableLabelProvider) { // tprov = (ITableLabelProvider) prov; // } // else { // lprov = (ILabelProvider) prov; // } int columnCount = table.getColumnCount(); String[] texts = new String[columnCount]; TableItem ti = (TableItem) item; for (int column = 0; column < columnCount; column++) { // Similar code in TableTreeViewer.doUpdateItem() // String text = ""; // Image image = null; // if (tprov != null) { // text = tprov.getColumnText(element, column); // image = tprov.getColumnImage(element, column); // } // else { // if (column == 0) { // text = lprov.getText(element); // image = lprov.getImage(element); // } // } texts[column] = text; // Apparently a problem to setImage to null if already null if (image != null || ti.getImage(column) != null) { ti.setImage(column, image); } } ti.setText(texts); } } long end_time = System.currentTimeMillis(); long elapsed = end_time - start_time; System.out.println("Columns="+columns+ " Rows=" + rows); System.out.println("Timed: "+elapsed+"ms"); while (!shell.isDisposed ()) { if (!display.readAndDispatch ()) display.sleep (); } image.dispose (); } } SN (3/7/01 1:57:37 PM) The results on J9, P2-400-128M: Columns=4 Rows=1000 Timed: 2850ms SN (3/7/01 2:49:53 PM) Need to try the above code on VA/Java EJP/SN (3/7/01 3:06:26 PM) Under JDK - P3-300 - 256M Columns=4 Rows=1000 Timed: 1161ms. Under VAJ (same machine) Columns=4 Rows=1000 Timed: 11927ms EJP (03/07/01 03:29:58 PM) Under VAJ Linux Columns=4 Rows=1000 Timed: 72075ms KR (3/8/01 4:43:26 PM) Linux, emulated Table on Windows: J9 - P3-550-256M Columns=4 Rows=1000 Timed: 16213ms on Linux: Timed: 20702ms Windows, native Table (same setup): Columns=4 Rows=1000 Timed: 2504ms SWT for Linux is > 20% slower. Linux Table needs to be 85% faster just to achieve same performance as Windows native widget (which apparently is still not good enough). Note: Benchmarks are without JIT KR (3/9/01 4:59:09 PM) Released new SWT code. Performance as follows (without JIT). J9 - P3-550-256M Windows (emulated Table): Columns=4 Rows=1000 Timed: 1943ms J9 - P3-550-128M Linux: Columns=4 Rows=1000 Timed: 2111ms With JIT on Windows (emulated Table): Columns=4 Rows=1000 Timed: 280ms With JIT on Linux: Columns=4 Rows=1000 Timed: 640ms
It would be great if there was a benchmark for this case. Randy, does your student have time to write one?
Improvements were made by the Java Core team to generate fewer errors. In addition, the TaskList now has a limit to the number of tasks it will display.