[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: Gtk2::TreeView performance



On Mon, 2006-12-04 at 16:12 +0100, Philipp E. Letschert wrote:
> Hi,
> 
> I've run into some performance troubles with Gtk2::TreeView.
> 
> What I do is: Read a file with a couple of ten-thousand of lines (or more),
> about 50 fields per line and build a hash from it. This is the data I put into a
> Gtk2::Liststore for the TreeView. Each row can be displayed colored, depending
> on a certain column value. The user can select which of the 50 columns he would
> like to see, after changes of this selection the whole TreeView is rebuild.
> 
> To make things more complicated each column should be sortable and reorderable,
> and the user should be able to perform actions on selected rows. All these
> things work, but it is amazingly slow, once the number of rows exceeds 10000.
> 
> 
> I've done lots of experimenting and some research and found these hints:
> 
> - set fixed with and fixed height
>   did this, but no real performance gain
> - disable sorting while building the treeview
>   did this via $colum->set_sortable(FALSE), but no real performance gain
> - write a custom cellrenderer
>   don't really know how to do this with performance in mind, just found the
>   cellrenderer_* examples in the docs
> - only load the rows into the treeview that actually fit into the window
>   no clue how to do this
> 
> It would be great if someone with a real clue could shed some light, if such a
> high-performance TreeView is possible with perl-gtk, and how an approach could
> look like.
> I'm afraid a possible answer could be: "No! use C++ instead".
> 
> Since a solution to this problem is interesting to me I would also like to help
> in developing some demo code for the examples section.  
> 

I experimented quite a bit with treeview performance (with some help by
muppet) for my program (gmusicbrowser). You don't need to use C/C++ to
have good performance, the speed of the song list in my program doesn't
depends only on the number of displayed rows.
I did it some time ago, so I may have forgotten/confused some things.
There is 2 distinct source of slowness:

The simpler problem is caused by the auto-sizing : (it seems you got
that bit)
 - if the column is set to auto-width, gtk2 has to compute the width of
every row, which of course will be slow for a big treeview, so you have
to set every column to fixed-width
 - Gtk2 also have to compute the height of every row (to correctly set
the scrollbar), that can be prevented by setting
$treeview->set('fixed-height-mode' => TRUE)


The harder-to-fix problem is the filling of the ListStore.

The only way to completely avoid that is to make your own ListStore, in
my case all the data were already in a perl array of array. So I made a
ListStore that just use the already existing perl array for storage. No
filling.
The only drawback is I have to tell gtk2 when the perl array has changed
by calling ListStore's row_inserted/row_deleted/row_changed methods or
unsetting/resetting the treeview model for a full update (but loose the
treeview state).
I'm sure it could be made cleaner with some Tied perl magic, but I fear
it could degrade performance.

A much simpler way, but that doesn't eliminate all the filling, is using
a one-column ListStore that just contains the index/key for each row.
Then you create columns with $treeview->insert_column_with_data_func(),
which use the index/key of the row to retrieve the data from your perl
arrary/hash, and set the cell properties accordingly.
Using a custom CellRenderer would work the same way, but it's more
suited when you want to draw things differently than with the existing
CellRenderers.

Both ways (custom ListStore and insert_column_with_data_func) have the
advantage, that you can easily add/remove columns, without rebuilding
the list.

You can check my program for an axample of custom ListStore
(http://squentin.free.fr/gmusicbrowser/download.html), in the
gmusicbrowser_list.pm file.
But be warned there is very few comments in the code, and it could use
some cleanups. Feel free to ask me for more explanations.

For sorting the list, I do it myself in perl, gtk2 can only sort the
list on one criteria, which has to be in the ListStore.

Quentin




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]