Archivio | febbraio 2014

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

Becoming Nebula Contributor

Hello everybody,
my name is Mirko Paturzo and i’m a software engineer working for Exeura S.r.l. (http://www.exeura.eu). I work primarily on Rialto, a data mining IDE whose UI is based on Eclipse RCP. I focus on user experience improvement via both UI and data-mining algorithms optimization.
I specialize in efficient multi-threading through thread and memory usage harnessing.
Since April 14, 2014 I became a committer of Nebula project.
I just started contributing to Nebula (http://www.eclipse.org/ nebula/) working on grid data handling subsystem, in order to reduce memory footprint, avoid some memory leaks, and improve overall rendering performance.
If you want, I can show in greater detail how this patch works in a later post.
Hope this helps,
Mirko