Objective Grid: How to fill a grid for best performance

Article ID: 483
Last updated: 25 Apr, 2018
Article ID: 483
Last updated: 25 Apr, 2018
Revision: 3
Views: 3031
Posted: 27 Jul, 2001
by Meltreger B.
Updated: 25 Apr, 2018
by Meltreger B.

Problem

 


When I fill a large grid with SetValueRange(), it is very slow.  How should I fill the grid with cells?

 

 


Cause

 


 

 


Action

 


  • If you call SetValueRange() for each cell, the grid will compute the cell, start the update mechanism (computing the window area, invalidate the cell, possibly send a hint to other views) and redraw the cell for each SetValueRange() call.


    Therefore, it is recommended that you call LockUpdate(TRUE) before you do several SetValueRange() calls.

Example: 
GetParam()->EnableUndo(FALSE); //Turn off undo buffer
BOOL bOldLock = LockUpdate(TRUE); //turn off all drawing
//loop through all the cells that you are changing
for (...)
{
      //get the values somehow...
      CString value = ...
      SetValueRange(CGXRange(nRow, nCol), value);
}
LockUpdate(bOldLock); //turn on drawing
Redraw(); //redraw updated grid

A further optimization is to call CGXData 's StoreStyleRowCol() instead of CGXGridCore's SetValueRange() because SetValueRange() has to check the read-only state for each cell and also sends a StoreStyle notification to each cell-type object before storing the value. But be aware that StoreStyleRowCol() will not create undo information, it will overwrite read-only cells, and it will not notify the control object associated with a cell.


Example: 
GetParam()-EnableUndo(FALSE); //Turn off undo buffer
BOOL bOldLock = LockUpdate(TRUE); //turn off all drawing

//get that data object
CGXData* pData = GetParam()->GetData();

CGXStyle* pStyle = CreateStyle();
pStyle->Free();//reset this style

//loop through all the cells that you are changing
for (...)
{
       //set the value into the style somehow
       pStyle->SetValue(...);
       //store it directly into the data object
       pData->StoreStyleRowCol(nRow, nCol, pStyle, gxOverride, 0);

}

RecyleStyle(pStyle);
LockUpdate(bOldLock); //turn on drawing
Redraw(); //redraw updated gri

If you are using the grid with the formula engine, the fastest way to fill the grid is to call SetNumberRowCol() and SetTextRowCol() directly. The speed improvements will be enormous compared to calling SetValueRange() or SetExpressionRowCol() for each cell. But again, be aware that cells are not checked for read-only status, cell objects are not notified, and no undo information is created.


Example:
 

// Performace tests:
// Using SetNumberRowCol/SetTextRowCol directly
// instead of SetValueRange or SetExpressionRowCol
// will speed up the initialization of the grid
// enormously (just as fast as filling an array).
//
// Check it out below!
//
// NOTE: Directly calling these methods will bypass the
// notification of the associated cell type object for a
// cell (CGXControl::StoreStyle will not be called) and
// the read-only state of the cell will also not be
// checked.
//
DWORD ti = GetTickCount();
CGXFormulaSheet* pSheet = GetSheetContext();
CGXStyle style;

for (; nRow < 300; nRow++)
{

for (ROWCOL nCol = 1; nCol < 10; nCol++)
{

// CString s;
// s.Format(%d/%d, nRow/100, nCol);
// style.SetValue(Hello);
// StoreStyleRowCol(nRow, nCol, &style, gxOverride, 0);

pSheet-SetNumberRowCol(nRow, nCol, (double) nRow+nCol);

// pSheet-SetTextRowCol(nRow, nCol, _T(Hello));

}

}

CString msg;
msg.Format(%d Ticks, GetTickCount()-ti);
AfxMessageBox(msg);

You may also take a look at the KB article How do I implement a virtual grid? I want to supply cell contents on demand.. Often the most preferred way to use the virtual grid is by overriding GetStyleRowCol() and StoreStyleRowCol(). When you intend to transfer many data to and from the grid, you might already maintain the data somewhere else, e.g. in a matrix or another data source (could also be a dbase file). In this case you should supply the data on demand and not copy all the values to and from the grid.


For example, if you have an array of strings, you may override GetStyleRowCol() and supply the grid with the necessary data when it needs them. Whenever the grid changes a cell's data, it calls StoreStyleRowCol(), so that data can be stored back into your matrix.

The VirtGrid tutorial steps you through overriding GetStyleRowCol() and StoreStyleRowCol() for use in a virtual grid.
The following samples may also be useful. Download Performance Sample 1 and Performance Sample 2.

This article was:   Helpful | Not helpful
Report an issue
Article ID: 483
Last updated: 25 Apr, 2018
Revision: 3
Views: 3031
Posted: 27 Jul, 2001 by Meltreger B.
Updated: 25 Apr, 2018 by Meltreger B.

Others in this category