Re: Gtk2::TreeView performance



On Mon, Dec 04, 2006 at 06:41:21PM +0100, Quentin wrote:
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

Hey Quentin,

your response was extremely helpful to me. I've downloaded gmusicbrowser and
found the relevant lines, that generate the custom store for the treeview.
I think this is exactly the sample code I was looking for. (I've found 
other things in your code to learn from as well...).

I'm going to try get it working and will contact you if I run into
troubles.

Thx! Philipp





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