Fill items performance

Hi!

What is the recommended way of filling items (rows) for a list?
I get a performance of approx. 300 items per second, when filling the items by looping over my itemlist to the table or an IndexedContainer - which seems way to slow?
CPU usage is at just 20%?

I am using addItem(idx) and then item.getItemProperty().SetValue()

If your CPU usage is truly at 20%, then 80% of the time is being spent elsewhere, i.e. not on the items proper. The 80% is being spent waiting for disk, network, swapping, etc. This is one of the paradoxes of performance tuning. It could be that your items are backed by a disk or database container, and that you are actually writing them to disk. It is then MUCH more efficient to store data using native capabilities (e.g. batch insert for SQL) and just reload the container, instead of going through the container layer (which is ok for one-item-at-a-time updates as performed by a user interface). Typical size for batches is 30-50 items – too big and you run into other issues.

No - really! My machine is fine!
I can loop through the same loop - without putting the 4000 records to a table/container, print its ids instead - and get done i a rush!!
Just putting my elements into a container/table (just 4 columns string/int) makes it that slow…

Further ideas?

Okay, lets say the CPU thing is a multi-core issue, and assume that the java process takes 100%… Why is filling items to a container/table so slow, and how can I achieve that faster than looping over each item and put it from the list to the container/table?

The table shall show items of a list I get from the EJB layer, so I have the final list m place already.
If looping over the list (<6000 elements) should be an issue, how can I else populate the table with the EJB data?

Well, I would say, your issue must be somewhere else as this little test runs in around 70ms:

package com.example.performancetest;

import java.util.Random;

import com.vaadin.Application;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.ObjectProperty;
import com.vaadin.ui.Table;
import com.vaadin.ui.Window;

public class PerformancetestApplication extends Application {
	
	private static final int ITEM_COUNT = 4000;
	
	private static class ItemDataGenerator {
		
		private Random r = new Random();
		
		public String[] createItemData() {
			String[] data = new String[4]
;
			data[0]
 = Integer.toString(r.nextInt());
			data[1]
 = Integer.toString(r.nextInt());
			data[2]
 = Integer.toString(r.nextInt());
			data[3]
 = Integer.toString(r.nextInt());
			
			return data;
		}
	}
	
	private Table table;
	
	@Override
	public void init() {
		Window mainWindow = new Window("Performancetest Application");
		
		ItemDataGenerator itemDataGenerator = new ItemDataGenerator();
		table = new Table();
		table.setContainerDataSource(createContainer(itemDataGenerator));
		
		mainWindow.addComponent(table);
		setMainWindow(mainWindow);
	}
	
	private Container createContainer(ItemDataGenerator itemDataGenerator) {
		Container c = new IndexedContainer();
		c.addContainerProperty("FIRST_COL_ID", String.class, "");
		c.addContainerProperty("SECOND_COL_ID", String.class, "");
		c.addContainerProperty("THIRD_COL_ID", String.class, "");
		c.addContainerProperty("FOURTH_COL_ID", String.class, "");
		
		long start = System.nanoTime();
		for(int i = 0; i < ITEM_COUNT; i++) {
			String[] data = itemDataGenerator.createItemData();
			
			Object itemId = c.addItem();
			Item item = c.getItem(itemId);
			
			Property prop = item.getItemProperty("FIRST_COL_ID");
			prop.setValue(data[0]
);
			
			prop = item.getItemProperty("SECOND_COL_ID");
			prop.setValue(data[1]
);
			
			prop = item.getItemProperty("THIRD_COL_ID");
			prop.setValue(data[2]
);
			
			prop = item.getItemProperty("FOURTH_COL_ID");
			prop.setValue(data[3]
);
		}
		long duration = System.nanoTime() - start;
		// Nano - Micro - Mili
		System.err.println("Elapsed Time: " + duration / 1000 / 1000 + "ms");
		
		return c;
	}

}

Adding an item to an IndexedContainer that is already attached to a Table usually causes the table to be notified and to refresh itself, which might slow down things quite a bit. If you are not using a custom container, I would recommend detaching the container from the table before performing large bulk updates and then reattaching it after the updates. You could also subclass IndexedContainer and use some of the protected internal add item methods that do not perform any filtering etc. and then just trigger all those operations at the end - read the source of IndexedContainer if you plan to do this.

On the other hand, a custom container (inheriting e.g. AbstractInMemoryContainer) might be a cleaner and perhaps also simpler approach here.

Thanks for helping me out on that!!

Currently I think that looping the list actually works fine as long as data is COMPLETELY pulled from the database.
In case I use fields that not are pulled already (nested objects…) - this it what populating the table/container slows down of course, and so is NO Vaadin related issue.

Thanks for your help - I will try to have a look at the container recommendation asap :slight_smile: