🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

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?
#1675
Author: Dan
Date: Thu, 28 Jun 2007 13:46
34 lines
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?
#1676
Author: PaoloItaly
Date: Thu, 28 Jun 2007 14:06
14 lines
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?
#1677
Author: Remy Lebeau (TeamB)
Date: Thu, 28 Jun 2007 16:23
58 lines
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?
#1684
Author: Dan
Date: Fri, 29 Jun 2007 17:55
88 lines
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?
#1685
Author: Remy Lebeau (TeamB)
Date: Fri, 29 Jun 2007 18:09
33 lines
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?
#1687
Author: Dan
Date: Fri, 29 Jun 2007 18:52
88 lines
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