Add wxGridTableBase::CanMeasureColUsingSameAttr()

This allows to optimize AutoSizeColumns() in the common case when all
cells in the same column can be measured using the same attribute.
This commit is contained in:
Vadim Zeitlin
2020-06-11 09:43:08 +02:00
parent 70768a33d2
commit 249db04dd3
3 changed files with 43 additions and 2 deletions

View File

@@ -1065,6 +1065,16 @@ public:
return wxGridCellAttrPtr(GetAttr(row, col, kind));
}
// This is an optimization for a common case when the entire column uses
// roughly the same attribute, which can thus be reused for measuring all
// the cells in this column. Override this to return true (possibly for
// some columns only) to speed up AutoSizeColumns() for the grids using
// this table.
virtual bool CanMeasureColUsingSameAttr(int WXUNUSED(col)) const
{
return false;
}
// these functions take ownership of the pointer
virtual void SetAttr(wxGridCellAttr* attr, int row, int col);
virtual void SetRowAttr(wxGridCellAttr *attr, int row);

View File

@@ -2517,6 +2517,25 @@ public:
returns @true.
*/
virtual bool CanHaveAttributes();
/**
Override to return true if the same attribute can be used for measuring
all cells in the given column.
This function is provided for optimization purposes: it returns @false
by default, but can be overridden to return @true when all the cells in
the same grid column use sensibly the same attribute, i.e. they use the
same renderer (either explicitly, or implicitly, due to their type as
returned by GetTypeName()) and the font of the same size.
Returning @true from this function allows AutoSizeColumns() to skip
looking up the attribute and the renderer for each individual cell,
which results in very noticeable performance improvements for the grids
with many rows.
@since 3.1.4
*/
virtual bool CanMeasureColUsingSameAttr(int col) const;
};

View File

@@ -9967,6 +9967,14 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction)
col = -1;
}
// If possible, reuse the same attribute and renderer for all cells: this
// is an important optimization (resulting in up to 80% speed up of
// AutoSizeColumns()) as finding the attribute and renderer for the cell
// are very slow operations, due to the number of steps involved in them.
const bool canReuseAttr = column && m_table->CanMeasureColUsingSameAttr(col);
wxGridCellAttrPtr attr;
wxGridCellRendererPtr renderer;
wxCoord extent, extentMax = 0;
int max = column ? m_numRows : m_numCols;
for ( int rowOrCol = 0; rowOrCol < max; rowOrCol++ )
@@ -10005,8 +10013,12 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction)
}
// get cell ( main cell if CellSpan_Inside ) renderer best size
wxGridCellAttrPtr attr = GetCellAttrPtr(row, col);
wxGridCellRendererPtr renderer = attr->GetRendererPtr(this, row, col);
if ( !canReuseAttr || !attr )
{
attr = GetCellAttrPtr(row, col);
renderer = attr->GetRendererPtr(this, row, col);
}
if ( renderer )
{
extent = column