PDA

View Full Version : How to optimize some code



Patrick Bennett
18 Mar 2014, 7:51 AM
Hey all,

I have a chunk of code that gets a chunk of JSON and adds it to a grid, and it seems awfully slow. I'm wondering if I'm doing things in the right order and in the most efficient way possible. Here's the code inside the "success:" part of the Ext.Ajax.request call:



var objResponse = Ext.JSON.decode(response.responseText),
objGridStore = Ext.getStore('GMInputs'),
arrRows = [], arrDates = [];

// Data comes from a REST service in a list of initiatives and dates, which needs to be turned into columns by day
Ext.each(objResponse.data, function(item, index, count) {
var arrDateParts = item.date.split('-'),
strDate = arrDateParts[1] + '/' + arrDateParts[2] + '/' + arrDateParts[0],
objRowDate = new Date(item.date);

if (!arrRows[strDate]) {
arrDates.push(strDate);
arrRows[strDate] = new SEI.model.GMInput();
arrRows[strDate].data.row_date = strDate;
}
arrRows[strDate].data['initiative_'+item.initiative_id + '_revenue'] = parseFloat(item.revenue);
arrRows[strDate].data['initiative_'+item.initiative_id + '_expense'] = parseFloat(item.expense);
arrRows[strDate].data['initiative_'+item.initiative_id + '_uniqueid'] = item.id;
});

// Now reformat the array to add it to the store
var arrDataToAdd = [];
Ext.each(arrDates, function(strDate, index, count) {
arrDataToAdd.push(arrRows[strDate]);
});

objGridStore.add(arrDataToAdd);

scottmartin
18 Mar 2014, 2:50 PM
Ouch ... so this cannot be handled at the server?

The immediate thing would be to replace each with a for loop.
Suspend your layouts and store events
Can you reformat the dates in the first loop?

Patrick Bennett
19 Mar 2014, 7:14 AM
Thanks for your comments. The back end for this is a REST service which produces the data in that format (a little too much REST Religion if you ask me, but...) and needs to be converted. I did write a "middleware" chunk of PHP code that I'm going to try out, but I have this code in production and need to tweak it as little as possible for right now since I'm already on to the next sprint.

Should I be suspending events before the add() and resuming after, or does it do that under the covers? Or maybe can you describe a pattern for bulk adding rows to a grid. I also thought that I should somehow wrap this into the store's load() method so it all happens under the covers and the grid sees it as just another store.

I will try the for loop first and see how that goes!

Patrick

Patrick Bennett
19 Mar 2014, 8:17 AM
Just the conversion of Ext.each() to for() cut the load time in more than half.

Also, in the date thing, would it be best to just put the data in the store as 'Y-m-d' and let the date format parameter convert it to 'm/d/Y'?

Oh and in response to your question about the dates, the data comes in as:

{initiative_id: 1, date: '2013-12-31', revenue: 5000.00, expense: 4000.00},
{initiative_id: 2, date: '2013-12-31', revenue: 600.00, expense: 300.00},
{initiative_id: 4, date: '2013-12-31', revenue: 924.00, expense: 1043.00},
{initiative_id: 32, date: '2013-12-31', revenue: 390.45, expense: 220.40},
etc.

But the grid has initiative_id as the column:

{date: '2013-12-31', initiative_1_revenue: 5000.00, initiative_1_expense: 4000.00, etc.}

So I have to collect up all the initiative data for a single date into one row to put it in the grid.

Actually maybe I should do the reformat in the second loop and just let it key by the data that comes back from the REST service. Going to try that.

Patrick

Patrick Bennett
19 Mar 2014, 8:35 AM
So this is what I ended up with after your suggestions (other than doing it all on the server). Much faster =)



var objResponse = Ext.JSON.decode(response.responseText),
objGridStore = Ext.getStore('GMInputs'),
arrRows = [],
strRowDate = null,
arrDateParts = null,
item = null,
strDate = null;

for (var intItem = 0; intItem < objResponse.data.length; intItem++) {
item = objResponse.data[intItem],
strDate = item.date;
if (!arrRows[strDate]) {
arrRows[strDate] = new SEI.model.GMInput();
arrDateParts = item.date.split('-');
arrRows[strDate].data.row_date = arrDateParts[1] + '/' + arrDateParts[2] + '/' + arrDateParts[0];
}
arrRows[strDate].data['initiative_'+item.initiative_id + '_revenue'] = parseFloat(item.revenue);
arrRows[strDate].data['initiative_'+item.initiative_id + '_expense'] = parseFloat(item.expense);
arrRows[strDate].data['initiative_'+item.initiative_id + '_uniqueid'] = item.id;
}
var arrDataToAdd = [];
for (var intDay in arrRows) {
arrDataToAdd.push(arrRows[intDay]);
}
objGridStore.add(arrDataToAdd, blnAppend);