listGrid performance issues on finds

All

We have a listGrid with 10 columns backed by a dataSource. Basically we receive an event from the server we do the following with the record

Grid is being built as follows

this.setDataSource(this.executionsDataSource);
		this.setAutoFetchData(true);
		this.setAlternateRecordStyles(false);
		this.setAlwaysShowEditors(false);
		this.setAutoFitFieldWidths(true);

we are using the

  1. Search the grid using getCellCSSText to style about 4 columns.

The datasource has just

setAutoCacheAllData(true);
.getListGrid().getRecordList().find(AsyncRecord.GRID_EXECID, execOrderId);
  1. If the record exists, we try and update a column in the already placed record. So almost like updating a price.
.getListGrid().updateData(record);
  1. If the record does not exist, we just do a
.getListGrid().addData(record);

Now these updates can come from the backend at a very quick rate in our testing. So we are unsure if it is the find method that is slow, or the listGrid just not updating when we insert a new record.

With the last test we just did, there were not many records only about 25. So I would think the find was quick enough.

Looking at the developer console all I see is

20:52:11.894:RDQ1:INFO:scrolling:isc_ExecutionsListGrid_0_body:Drawn size: 1805 by 1804, specified: 1532 by 289, scrollbar state: hv
20:52:11.910:RDQ1:INFO:drawing:isc_ExecutionsListGrid_0_body:redrawPeers(): 2 peers
20:52:11.910:RDQ1:DEBUG:drawing:isc_ExecutionsListGrid_0_body:Redraw() - Total time to redraw in DOM:163
20:52:12.263:TMR7:INFO:redraws:isc_ExecutionsListGrid_0_body:Scheduling redraw (dataChanged)
    Class.getStackTrace(_1=>undef,  _2=>undef,  _3=>undef,  _4=>undef)
    Canvas.$q9(_1=>"dataChanged",  _2=>undef)
    Canvas.markForRedraw(_1=>"dataChanged", undef, undef, undef, undef)
    Array.map(_1=>"markForRedraw",  _2=>"dataChanged",  _3=>undef,  _4=>undef,  _5=>undef,  _6=>undef)
    ListGrid.$25a(_1=>"dataChanged")
    ListGrid.dataChanged(_1=>undef,  _2=>undef,  _3=>undef,  _4=>undef,  _5=>undef)
    dataChangedObservation(operationType=>undef,  originalRecord=>undef,  rowNum=>undef,  updateData=>undef,  filterChanged=>undef)
    ResultSet.$ee(_1=>undef)
    ResultSet.handleUpdate(_1=>"add",  _2=>Obj{ID:1317667489072},  _3=>undef,  _4=>Obj)
    ResultSet.dataSourceDataChanged(_1=>Obj,  _2=>Obj)
    dataChangedObservation(dsResponse=>Obj,  dsRequest=>Obj)
    DataSource.updateCaches(_1=>Obj,  _2=>Obj)
    [c]DataSource.handleUpdate(_1=>Obj,  _2=>Obj)
    DataSource.fireResponseCallbacks(_1=>Obj,  _2=>Obj,  _3=>Obj,  _4=>Obj)
    DataSource.$38b(_1=>Obj,  _2=>Obj,  _3=>Obj,  _4=>Obj,  _5=>Obj)
    DataSource.$50e(_1=>Obj,  _2=>Obj,  _3=>Obj)
    [c]Class.fireCallback(_1=>Obj,  _2=>"rpcResponse,data,rpcRequest",  _3=>Array[3],  _4=>[DataSource ID:isc_ExecutionsDataSource_0],  _5=>undef) on [Class RPCManager]
    Class.fireCallback(_1=>Obj,  _2=>"rpcResponse,data,rpcRequest",  _3=>Array[3],  _4=>undef)
    [c]RPCManager.__fireReplyCallback(_1=>Obj,  _2=>Obj,  _3=>Obj,  _4=>Obj)
    anonymous(b=>Obj,  c=>Obj,  d=>Obj,  e=>Obj)
    [c]RPCManager.fireReplyCallbacks(_1=>Obj,  _2=>Obj)
    [c]RPCManager.performOperationReply(_1=>Obj,  _2=>Obj)
    [c]RPCManager.$39d(_1=>502)
    ** recursed on [c]Class.fireCallback

20:52:12.353:RDQ1:INFO:drawing:isc_ExecutionsListGrid_0_body:$ra(): redrawing
20:52:12.437:RDQ1:DEBUG:gridHTML:isc_ExecutionsListGrid_0_body:getTableHTML: columns 0->25, rows 0->17, time: 84ms (468 cells at 0.18ms per cell, 5571.43 cells per second), spacerHeights: [0,1452], left/right pad: [0,0], 0 single cell rows
20:52:12.502:RDQ1:INFO:sizing:isc_ExecutionsListGrid_0_body:Specified size: 1532x289, drawn scroll size: 1805x1848, border: 0x0, margin: 0x0, reason: redraw
20:52:12.502:RDQ1:DEBUG:sizing:isc_ExecutionsListGrid_0_body:clipHandle sizes: {scrollLeft: 0,
scrollTop: 0,
scrollWidth: 1805,
scrollHeight: 1848,
clientWidth: undef,
clientHeight: undef,
offsetWidth: 1516,
offsetHeight: 273,
styleLeft: "0px",
styleTop: "23px",
styleWidth: "1516px",
styleHeight: "273px",
styleClip: ""}
20:52:12.503:RDQ1:DEBUG:sizing:isc_ExecutionsListGrid_0_body:handle sizes: {scrollLeft: 0,
scrollTop: 0,
scrollWidth: 1805,
scrollHeight: 1848,
clientWidth: undef,
clientHeight: undef,
offsetWidth: 1516,
offsetHeight: 1848,
styleLeft: "",
styleTop: "",
styleWidth: "",
styleHeight: "",
styleClip: ""}
20:52:12.503:RDQ1:INFO:scrolling:isc_ExecutionsListGrid_0_body:Drawn size: 1805 by 1848, specified: 1532 by 289, scrollbar state: hv
20:52:12.503:RDQ1:INFO:drawing:isc_ExecutionsListGrid_0_body:redrawPeers(): 2 peers
20:52:12.503:RDQ1:DEBUG:drawing:isc_ExecutionsListGrid_0_body:Redraw() - Total time to redraw in DOM:150

And looking at the RPC tab i see the updates , deletes and adds any they say success in 103ms.

Is there a way to dig deeper to see what the issue could be… Or are we trying to get a bit much from the listGrid?

Thats quite trivial and not a problem, you can see in the EE Showcase a grid being continuously updated with no issues. Part of the problem is that you’ve enabled extremely verbose logging, which has a major performance impact.

Other than that, check how many times you are actually running your code. Sometimes a simple bug means you are running it 10,000 times instead of the intended once.

Thanks for the response. I have looked at the http://www.smartclient.com/smartgwtee/showcase/#messaging_stock_quotes example and see the updates coming in. And it seems you are using the

Record record = stockQuotesGrid.getDataAsRecordList().find("id", id);

Similar to what we are doing. I have noticed that there is a

Thread.sleep(500);

how low can this be taken down?

That depends on browser/version/OS/CPU and the amount of processing you do. But you are basically unlikely to hit limits here relative to how much a human can actually absorb.

I agree humans can only process at 200ms. I guess then I have something else wrong, as my code is almost the same as yours. I will review again.

I am running a mac and using Firefox, very well spec so I would not think this should be a problem. Will look again at the find command and record object setup.

So I ran my test again. And i Put some logging into my find code


DataRecord record = (DataRecord)this.display.getListGrid().getResultSet().find(DataRecord.GRID_EXECID, execOrderId);

if(record == null) {
logger.warning("DataExecution does not exists " + exec + " creating " + type);
   this.display.getListGrid().addData(record);
}

No some of them do get found but some do not. I find this very strange as you can see they are in the grid.

Sorry logging is now off. So I still think the issue is with the find, how to i debug.

Sorry just through I would give you the requirements that we are trying to test.

Basically the server will send a Record from the backend. We want to insert this record into the listgrid, and then wait for the next record with the sameId to come from the server again. Like an update event.

So our logic is this

on event received, check that the listGrid contains the event, if so update it, if not add it. This can happy every 500ms. We can receive a huge amount of events then a slow down.

Further testing has found the following to work. but this is not a nice way of doing it

public void executionAcknowledgementReceived(final DataRecord data, boolean firstTime) {

DataRecord record = (DataRecord)this.display.getListGrid().getRecordList().find(DataRecord.GRID_EXECID, data.execOrderId);
		
		if(record == null) {
			if(firstTime) {
				Timer t = new Timer() {
					public void run() {
						        receivedEvent(data, false);
					}
				};
				// Schedule the timer to run once in 5 second.
				t.schedule(500);
				return;
				
			}
               }

            // If stil null add, if not update
}

Just reiterating, none of this is actually necessary as demonstrated by the working example, which does the same thing and is not slow. Let us know if you discover the actual cause of your performance problem.

The working example and what I have posted are different. The working example is populated with rows already. I am inserting a row, then coming along and looking for a row, then either updating or removing that row. So lots of add,update,delete.

The example is just looking for a static row, and update a column. So my question again, is the grid able to handle that?

Of course. That’s easier if anything.

If it’s not obvious, no one on the forums (Isomorphic or other) can help you debug a performance or interactivity problem based on posting just a few code snippets. Something runnable is required.

Understand let me knock something up.