Grid Contribution: Performance improvement.

Hi everybody,
I try to briefly describe the changes made on the Nebula Grid component.
The main problems of the component were the following:

1) excessive memory usage
2) management of data visualization decentralized and not customizable
3) memory leaks in component dispose

Excessive memory usage is due to the duplication of data display, such as text, rowspan, colspan, fonts, background, foreground, and many others.
This information was contained in objects called GridItem. Each GridItem contains information on how it should be represented in the grid.

Suppose we have a simple table that represents a collection of 1,000 objects of the following type:

class Person {
   int counter; //simple id
   String name, surname, address, ... 997 other strings ...
}

Imagining then you want to highlight only pair rows, we have to keep track for each cell, its background, its font and its foreground.

In summary, for each row, the GridItem duplicate data as strings, fonts, foreground, and much more ..

With the old implementation, a table of 1,000,000 cells in memory, weighs about 400mb.

The first step was to centralize all the information related to the graphics of the grid cells and place them in a data visualization manager that implements the interface DataVisualizer.
The GridItem ask how to draw itself DataVisualizer.

At this point we can build our manager.

An example of DataVisualizer

class MyOwnDataVisualizer extends AdaptedDataVisualizer {
	FontRegistry registry = new FontRegistry();
	private final MyModel models[];

	public MyOwnDataVisualizer(MyModel models[]) {
		this.models = models;
	}

	@Override
	public Image getImage(GridItem item, int columnIndex) {
		return null;
	}

	@Override
	public String getText(GridItem item, int columnIndex) {
		return "Column " + columnIndex + " => " + models[item.getRowIndex()].toString();
	}

	@Override
	public Font getFont(GridItem item, int columnIndex) {
		if ((models[item.getRowIndex()]).counter % 2 == 0) {
			return registry.getBold(Display.getCurrent().getSystemFont()
					.getFontData()[0].getName());
		}
		return null;
	}

	@Override
	public Color getBackground(GridItem item, int columnIndex) {
		if ((models[item.getRowIndex()]).counter % 2 == 0) {
			return Display.getCurrent().getSystemColor(SWT.COLOR_RED);
		}
		return Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
	}

	@Override
	public Color getForeground(GridItem item, int columnIndex) {
		if ((models[item.getRowIndex()]).counter % 2 == 1) {
			return Display.getCurrent().getSystemColor(SWT.COLOR_RED);
		}
		return Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
	}
}


no more unnecessary copies of data visualization. In this case, table memory usage is about 40mb!

Snippets!

http://git.eclipse.org/c/nebula/org.eclipse.nebula.git/tree/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithAdaptedDataVisualizer.java
http://git.eclipse.org/c/nebula/org.eclipse.nebula.git/tree/examples/org.eclipse.nebula.snippets/src/org/eclipse/nebula/snippets/grid/viewer/GridViewerSnippetWithGridItemDataVisualizer.java

Mirko

Tag:, , , ,

Lascia un commento