Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages
Started by Dan
Thu, 28 Jun 2007 13:46
Best way to clear a stringgrid?
Author: Dan
Date: Thu, 28 Jun 2007 13:46
Date: Thu, 28 Jun 2007 13:46
34 lines
1901 bytes
1901 bytes
Hi, I want to clear a string grid, and I'd like to do it quickly.
What is the best way to do that?
The problem that I am having is that for REALLY LARGE grids, clearing
the grid takes a long time. I'd like to see quick performance like I
see when I close the app. Would it be best to delete the grid and
recreate it instead?
This is my code:
void ClearStringGrid(TStringGrid* sgGrid)
{
const bool OldVisible = sgGrid->Visible;
sgGrid->Visible = false;
Application->ProcessMessages();
for (int Row = 0; Row< sgGrid->RowCount; Row++)
{
for (int Col = 0; Col< sgGrid->ColCount; Col++)
{
//this process is slow, but needed
//if I don't do this, and just change the col/row counts
//then the cells may still have values.
sgGrid->Cells[Col][Row] = "";
sgGrid->Objects[Col][Row] = NULL;
}
}
sgGrid->ColCount=0;
sgGrid->RowCount=0;
sgGrid->ColWidths[0] = 50;
sgGrid->Cells[0][0] = "";
sgGrid->Visible = OldVisible;
}
Re: Best way to clear a stringgrid?
Author: PaoloItaly
Date: Thu, 28 Jun 2007 14:06
Date: Thu, 28 Jun 2007 14:06
14 lines
1495 bytes
1495 bytes
sgGrid->ColCount=0;
sgGrid->RowCount=0;
"Dan" <Dan@do.not.spam> ha scritto nel messaggio
news:4683bbbe$1@newsgroups.borland.com...
> Hi, I want to clear a string grid, and I'd like to do it quickly.
>
> What is the best way to do that?
>
> The problem that I am having is that for REALLY LARGE grids, clearing the
> grid takes a long time. I'd like to see quick performance like I see when
> I close the app. Would it be best to delete the grid and recreate it
> instead?
>
Re: Best way to clear a stringgrid?
Author: Remy Lebeau (TeamB)
Date: Thu, 28 Jun 2007 16:23
Date: Thu, 28 Jun 2007 16:23
58 lines
2845 bytes
2845 bytes
"Dan" <Dan@do.not.spam> wrote in message
news:4683bbbe$1@newsgroups.borland.com...
> What is the best way to do that?
There are three ways to "clear" a TStringGrid:
1) If you want to remove all of the rows, then set the RowCount
property to (FixedRows+1) and then Clear() the remaining row by
itself. A TStringGrid must always have at least 1 non-fixed row at
all times. The RowCount cannot be set to 0. Don't ask me why, I
don't know why Borland designed TStringGrid that way.
2) If you do not want to remove all of the rows, then either:
a) loop through the Rows[] list calling Clear() on each one
b) loop through the Cells[][] property (which ou are doing)
> The problem that I am having is that for REALLY LARGE grids,
> clearing the grid takes a long time. I'd like to see quick
performance
> like I see when I close the app.
Then I suggest not using a TStringGrid at all. A TListView in virtual
mode (OwnerData = true) would be a lot faster, not to mention have a
cleaner look in general.
> Would it be best to delete the grid and recreate it instead?
Not really.
> This is my code:
It is not necessary to loop through the Cells[][] and Objects[][]
properties as well as set the Row/ColCount properties at the same time
like you are doing. Simply setting the Row/ColCount is enough to
remove all of the affected cell values just fine.
> //this process is slow, but needed
> //if I don't do this, and just change the col/row counts
> //then the cells may still have values.
That is not true. All rows/columns that are removed are freed from
memory. There is nothing physically available for the TStringGrid to
keep displaying for them.
Try this:
void ClearStringGrid(TStringGrid* sgGrid)
{
sgGrid->RowCount = (sgGrid->FixedRows+1);
sgGrid->Rows[sgGrid->FixedRows]->Clear();
}
Gambit
Re: Best way to clear a stringgrid?
Author: Dan
Date: Fri, 29 Jun 2007 17:55
Date: Fri, 29 Jun 2007 17:55
88 lines
3930 bytes
3930 bytes
> That is not true. All rows/columns that are removed are freed from
> memory. There is nothing physically available for the TStringGrid to
> keep displaying for them.
>
> Try this:
>
> void ClearStringGrid(TStringGrid* sgGrid)
> {
> sgGrid->RowCount = (sgGrid->FixedRows+1);
> sgGrid->Rows[sgGrid->FixedRows]->Clear();
> }
>
The above doesn't work. Indeed it creates the image that the gridis
cleared and it 'looks' like everything is gone, but simply set the
Row/Column count back again and you will see that the strings that were
entered into the grid are still there.
For example, creating some basic test code like the following including
three buttons aptly named "ResizeGridButton", "FillGridButton", and
"ClearGridButton" and one stringgrid named StringGrid1, and you will see
what I mean when you assign the appropraite events to each:
//---------------------------------------------------------------------------
void __fastcall TForm1::ResizeGridButtonClick(TObject *Sender)
{
StringGrid1->RowCount = 10;
StringGrid1->ColCount=10;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FillGridButtonClick(TObject *Sender)
{
ResizeGridButtonClick(this);
for (int i=0; i<10;i++)
{
for (int j=0; j<10; j++)
{
StringGrid1->Cells[i][j] = i+j;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClearGridClick(TObject *Sender)
{
ClearStringGrid(StringGrid1);
}
//---------------------------------------------------------------------------
In the GUI, click the FillGrid button, then the ClearGrid button, then
the ResizeGrid button and you will notice that even though the 'clear
grid' button cleared the grid visually, when you resize it you will see
that a large number of values still exist.
Based on the results from above, I did modify the ClearStringGrid code
to the following:
//---------------------------------------------------------------------------
void ClearStringGrid(TStringGrid* sgGrid)
{
if (sgGrid->RowCount < sgGrid->ColCount)
{
//clear all the rows if there are less rows than columns
for (int i=0; i<sgGrid->RowCount; i++)
{
sgGrid->Rows[i]->Clear();
}
}
else
{
//clear all the columns if there are less columns than rows
for (int i=0; i<sgGrid->ColCount; i++)
{
sgGrid->Cols[i]->Clear();
}
}
sgGrid->ColCount=1;
sgGrid->RowCount=1;
}
Even the above though takes nearly 10 seconds to clear a Grid containing
275K rows and only 4 columns on my 2GHz DUO-Core WinXP system with 2GB
of RAM. Yes, it's faster than the original code, but I expect faster.
Am I wrong to expect that this clearing process should be possible in
less than a second?
Dan
Re: Best way to clear a stringgrid?
Author: Remy Lebeau (TeamB)
Date: Fri, 29 Jun 2007 18:09
Date: Fri, 29 Jun 2007 18:09
33 lines
2314 bytes
2314 bytes
"Dan" <Dan@do.not.spam> wrote in message news:46854789.701@do.not.spam... > The above doesn't work. Indeed it creates the image that the gridis > cleared and it 'looks' like everything is gone, but simply set the > Row/Column count back again and you will see that the strings that were > entered into the grid are still there. Looking at the source code for TStringGrid, I do not see it ever shrinking the memory used for the Rows and Cols until the TStringGrid is destroyed. The memory only grows when needed. > Even the above though takes nearly 10 seconds to clear a Grid > containing 275K rows You should not be using a TStringGrid to display that many rows to begin with. It is not designed to handle large amounts of data. I would suggest using a virtual TListView instead (set the OwnerData property to True and use the OnData event). Then you can perform your own data management and optimize it for better speed and efficiency since the data is decoupled from the UI. > Am I wrong to expect that this clearing process should be possible > in less than a second? Yes. TStringGrid is not designed for large amounts of data. There is a lot of maintenance going on internally, so it is going to slow down the more data you put into it. Gambit
Re: Best way to clear a stringgrid?
Author: Dan
Date: Fri, 29 Jun 2007 18:52
Date: Fri, 29 Jun 2007 18:52
88 lines
3975 bytes
3975 bytes
> That is not true. All rows/columns that are removed are freed from
> memory. There is nothing physically available for the TStringGrid to
> keep displaying for them.
>
> Try this:
>
> void ClearStringGrid(TStringGrid* sgGrid)
> {
> sgGrid->RowCount = (sgGrid->FixedRows+1);
> sgGrid->Rows[sgGrid->FixedRows]->Clear();
> }
>
The above doesn't work. Indeed it creates the image that the gridis
cleared and it 'looks' like everything is gone, but simply set the
Row/Column count back again and you will see that the strings that were
entered into the grid are still there.
For example, creating some basic test code like the following including
three buttons aptly named "ResizeGridButton", "FillGridButton", and
"ClearGridButton" and one stringgrid named StringGrid1, and you will see
what I mean when you assign the appropraite events to each:
//---------------------------------------------------------------------------
void __fastcall TForm1::ResizeGridButtonClick(TObject *Sender)
{
StringGrid1->RowCount = 10;
StringGrid1->ColCount=10;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FillGridButtonClick(TObject *Sender)
{
ResizeGridButtonClick(this);
for (int i=0; i<10;i++)
{
for (int j=0; j<10; j++)
{
StringGrid1->Cells[i][j] = i+j;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ClearGridClick(TObject *Sender)
{
ClearStringGrid(StringGrid1);
}
//---------------------------------------------------------------------------
In the GUI, click the FillGrid button, then the ClearGrid button, then
the ResizeGrid button and you will notice that even though the 'clear
grid' button cleared the grid visually, when you resize it you will see
that a large number of values still exist.
Based on the results from above, I did modify the ClearStringGrid code
to the following:
//---------------------------------------------------------------------------
void ClearStringGrid(TStringGrid* sgGrid)
{
if (sgGrid->RowCount < sgGrid->ColCount)
{
//clear all the rows if there are less rows than columns
for (int i=0; i<sgGrid->RowCount; i++)
{
sgGrid->Rows[i]->Clear();
}
}
else
{
//clear all the columns if there are less columns than rows
for (int i=0; i<sgGrid->ColCount; i++)
{
sgGrid->Cols[i]->Clear();
}
}
sgGrid->ColCount=1;
sgGrid->RowCount=1;
}
Even the above though takes nearly 10 seconds to clear a Grid containing
275K rows and only 4 columns on my 2GHz DUO-Core WinXP system with 2GB
of RAM. Yes, it's faster than the original code, but I expect faster.
Am I wrong to expect that this clearing process should be possible in
less than a second?
Dan
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads