Re: ideas on improving the performance of gtk_tree_view

2007-04-15 Thread markku . vire

Hi,

Lainaus Federico Mena Quintero [EMAIL PROTECTED]:

 El jue, 29-03-2007 a las 17:43 +0300, [EMAIL PROTECTED] escribió:
 
  Using arrays in GtkTreeDataSortHeader doesn't appear to be optimal,
  because their length is not constant. We would end up to 
  alloc/dealloc/copy sequence when adding new items. 
 
 From a quick look at the code, the only place where
 _gtk_tree_data_list_header_new() gets called is from
 gtk_list_store_set_n_columns(), which is an internal construct-time
 function.  So the number of headers cannot change.
 

Wouldn't it be possible that calling gtk_tree_sortable_set_sort_func
with some strange sort_column_id causes _gtk_tree_data_list_set_header 
to append new items to header list? At least it contains the code 
to create new items.

  However, why this step is needed at all for each comparisison!! 
  It's certainly the case that there will be more sort function calls 
  than changes to sort criteria. This would allow us to cache the pointer 
  to active GtkTreeDataSortHeader directly, providing us constant time 
  O(1) access. Or did I miss something?
 
 Oh, you are completely right!  You could indeed cache the current
 header and only refresh it when the sort_column_id changes.
 
 Who's got a patch burning a hole in their pocket? :)

I made my first try :) There is now a new bug in bugzilla to follow 
the patches related to this matter: 
http://bugzilla.gnome.org/show_bug.cgi?id=430095

-Markku-
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-04-09 Thread Federico Mena Quintero
El jue, 29-03-2007 a las 17:43 +0300, [EMAIL PROTECTED] escribió:

 Using arrays in GtkTreeDataSortHeader doesn't appear to be optimal,
 because their length is not constant. We would end up to 
 alloc/dealloc/copy sequence when adding new items. 

From a quick look at the code, the only place where
_gtk_tree_data_list_header_new() gets called is from
gtk_list_store_set_n_columns(), which is an internal construct-time
function.  So the number of headers cannot change.

[Same thing for gtktreesort.c - it only creates the headers when you
change the underlying model.]

 However, why this step is needed at all for each comparisison!! 
 It's certainly the case that there will be more sort function calls 
 than changes to sort criteria. This would allow us to cache the pointer 
 to active GtkTreeDataSortHeader directly, providing us constant time 
 O(1) access. Or did I miss something?

Oh, you are completely right!  You could indeed cache the current
header and only refresh it when the sort_column_id changes.

Who's got a patch burning a hole in their pocket? :)

  Federico

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-29 Thread markku . vire

Hi,

On Mon, 2007-03-26 at 19:06 -0600, Federico Mena Quintero wrote:
I was looking at the GtkTreeView code and it looks like there are other
 places that could get the array treatment.  One place in particular was
 the sorting machinery... GtkListStore also uses a GList of information
 for the sort headers, and walks the list in g_list_store_compare_func
 (!).
 

Using arrays in GtkTreeDataSortHeader doesn't appear to be optimal,
because their length is not constant. We would end up to 
alloc/dealloc/copy sequence when adding new items. 

They are also accessed according to sort_id (which can come from 
application program and are not neccesarily contiguous). This means 
that if we would have an ordered vector we could reach O(log n) 
search time. Yes, it's better than current O(n) one. 

However, why this step is needed at all for each comparisison!! 
It's certainly the case that there will be more sort function calls 
than changes to sort criteria. This would allow us to cache the pointer 
to active GtkTreeDataSortHeader directly, providing us constant time 
O(1) access. Or did I miss something?

-Markku- 
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: Speeding up stroking of dashed rectangles (was: ideas on improving the performance of gtk_tree_view)

2007-03-28 Thread Nicolas Setton
 What hadn't ever been made clear is if real-world applications were
 seeing performance problems caused by the dashed stroking. It sounds
 like maybe you're on to one of those now.

To be fair, even though it's a justifiable use, that's an extreme  
case - with the font I'm using, one tree row is more than one hundred  
thousand pixels long.

   if (stroke_style-dash)
   return CAIRO_INT_STATUS_UNSUPPORTED;

 After you do that, the results won't be correct, (the focus rectangle
 will come out solid instead of dashed), but it should give you a
 feeling of the upper-bound of the performance benefit you could expect
 from adding dash support to this function, (and also confirm if the
 dashed stroking is the cause of the problems you're seeing).

I commented out the line, and, as expected, the performance becomes  
good. The response time was divided by about 100!

 And if so, then yes, the cairo list might be the best place to
 continue the discussion. In fact, I just decided to pull that list in
 with this reply. Please feel free to drop gtk-devel-list from future
 replies if we just keep talking about cairo's dashed stroking code.

I've kept gtk-devel-list to inform everyone of the results, since  
that's one more argument in favor of integrating Markku's patch.

I'll also take the opportunity to thank again everyone involved in  
these productive discussions. This is one healthy community!

Carl, see you in the cairo list for the continuation of this :) I'll  
try submitting a pertinent test for integration in the perf/ suite,  
and then a tentative implementation of dash support in  
_cairo_path_fixed_stroke_rectilinear.

Nico
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-27 Thread Nicolas Setton


 Nicolas, can you get another profile using Markku's patch?

Most certainly!

A couple of preliminary remarks.

I have observed a startup time increase of between 20% and 30%.

When scrolling, here is what I observed:
   - when displaying the selected row, performance is as bad as  
before (scrollbars take between 5 and 15 seconds to react)
   - when not displaying the selected row, performance is acceptable  
(scrollbars take between 0 and 2 seconds to react, and I'm compiling  
at -O0)

An interesting point to note is that this seems due to the drawing of  
the keyboard input rectangle (the dotted lines rectangle): when I  
select a row with the mouse, the interface is snappy, both for  
selecting and for scrolling (between 0 and 2 seconds response time),  
but when I then change the selected row using Up or Down keys, the  
interface takes around 10 seconds to highlight the newly selected row.
Maybe the experts will have an idea why this is so?

Let's have a look at the relevant time profile (line N calls line N+1):

SelfTotal   Library Symbol

0.0%73.7%   libgtk-x11-2.0.0.dylib  gtk_main
0.0%73.7%   libglib-2.0.0.dylib g_main_loop_run 
0.0%73.7%   libglib-2.0.0.dylib g_main_context_iterate  
0.0%73.6%   libglib-2.0.0.dylib g_main_context_dispatch 
0.0%73.6%   libglib-2.0.0.dylib g_main_dispatch 
0.0%71.8%   libglib-2.0.0.dylib g_idle_dispatch 
0.0%71.8%   libgdk-x11-2.0.0.dylib  gdk_threads_dispatch
0.0%71.8%   libgdk-x11-2.0.0.dylib  gdk_window_update_idle  
0.0%71.8%   libgdk-x11-2.0.0.dylib  gdk_window_process_all_updates  
0.0%71.8%   libgdk-x11-2.0.0.dylib  gdk_window_process_updates_internal 
0.0%71.8%   libgtk-x11-2.0.0.dylib  gtk_main_do_event   
0.0%71.8%   libgtk-x11-2.0.0.dylib  gtk_widget_send_expose  
0.0%71.8%   libgtk-x11-2.0.0.dylib  gtk_widget_event_internal   
0.0%71.8%   libgobject-2.0.0.dylib  g_signal_emit   
0.0%71.8%   libgobject-2.0.0.dylib  g_signal_emit_valist
0.0%71.8%   libgobject-2.0.0.dylib  signal_emit_unlocked_R  
0.0%71.8%   libgobject-2.0.0.dylib  g_closure_invoke
0.0%71.8%   libgobject-2.0.0.dylib  g_type_class_meta_marshal   
0.0%71.8%   libgtk-x11-2.0.0.dylib  _gtk_marshal_BOOLEAN__BOXED 
0.0%71.8%   libgtk-x11-2.0.0.dylib  gtk_tree_view_expose
0.1%71.5%   libgtk-x11-2.0.0.dylib  gtk_tree_view_bin_expose
0.0%67.0%   libgtk-x11-2.0.0.dylib  gtk_paint_focus 
0.0%67.0%   libgtk-x11-2.0.0.dylib  gtk_default_draw_focus  
0.0%67.0%   libcairo.2.dylibcairo_stroke
0.0%67.0%   libcairo.2.dylibcairo_stroke_preserve   
0.0%67.0%   libcairo.2.dylib_cairo_gstate_stroke
0.0%67.0%   libcairo.2.dylib_cairo_surface_stroke   
0.0%67.0%   libcairo.2.dylib_cairo_surface_fallback_stroke  
0.0%66.9%   libcairo.2.dylib_clip_and_composite_trapezoids  
0.0%66.8%   libcairo.2.dylib_cairo_traps_extract_region 
0.0%66.8%   libcairo.2.dylib_cairo_pixman_region_union_rect 
0.0%66.8%   libcairo.2.dylib_cairo_pixman_region_union  
9.7%66.7%   libcairo.2.dylibpixman_op   


A bit of analysis, now. As before the patch, most of the time is  
spent in gtk_tree_view_bin_expose.
If we have a closer look at the previous hot spot, here's what we see:

SelfTotal   LineCode

4240  /* we *need* to set cell data on all cells before 
the  
call
4241   * to _has_special_cell, else _has_special_cell() 
does  
not 
4242   * return a correct value.
4243   */   
4244  for (list = (rtl ? g_list_last (tree_view-priv- 
 columns) : g_list_first (tree_view-priv-columns));  
4245   list;
12.5%   0.0%4246   list = (rtl ? list-prev : list-next))  

4247{   
28.1%   0.0%4248  GtkTreeViewColumn *column = list-data;   

3.1%5.6%4249  gtk_tree_view_column_cell_set_cell_data 
(column,  
4250   
tree_view-priv-model,  
4251   
iter,   
4252   
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
4253   
node-children?TRUE:FALSE);  
4254}   


We spend between 3 and 4% of the time 

Re: ideas on improving the performance of gtk_tree_view

2007-03-27 Thread Kalle Vahlman
2007/3/27, Nicolas Setton [EMAIL PROTECTED]:


  Nicolas, can you get another profile using Markku's patch?

 Most certainly!

 A couple of preliminary remarks.

 I have observed a startup time increase of between 20% and 30%.

 When scrolling, here is what I observed:
- when displaying the selected row, performance is as bad as
 before (scrollbars take between 5 and 15 seconds to react)
- when not displaying the selected row, performance is acceptable
 (scrollbars take between 0 and 2 seconds to react, and I'm compiling
 at -O0)

 An interesting point to note is that this seems due to the drawing of
 the keyboard input rectangle (the dotted lines rectangle): when I
 select a row with the mouse, the interface is snappy, both for
 selecting and for scrolling (between 0 and 2 seconds response time),
 but when I then change the selected row using Up or Down keys, the
 interface takes around 10 seconds to highlight the newly selected row.
 Maybe the experts will have an idea why this is so?

What's your Cairo version? The input focus rectangle has been
identified as a performance problem some time ago:

http://lists.freedesktop.org/archives/cairo/2006-October/008135.html
Another thing we identified at GUADEC is that the dashed stroke for
the focus rectangle that GTK+ uses is also a performance problem. This
is another case that we should ensure is going through the fast path
for whole-pixel regions.

though I *think* it has been adressed since. But if you are running
1.4, that would hint that it still is a problem.

P.S. The performance-list[1] might be a better place for this discussion...

[1] http://mail.gnome.org/mailman/listinfo/performance-list

-- 
Kalle Vahlman, [EMAIL PROTECTED]
Powered by http://movial.fi
Interesting stuff at http://syslog.movial.fi
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Speeding up stroking of dashed rectangles (was: ideas on improving the performance of gtk_tree_view)

2007-03-27 Thread Carl Worth
On Tue, 27 Mar 2007 17:50:08 +0200, Nicolas Setton wrote:
 Interesting, the dashed stroke is exactly what's causing problems -
 thanks for the pointer!

Ah, ...

  though I *think* it has been adressed since. But if you are running
  1.4, that would hint that it still is a problem.

 There have been great advances in cairo performance lately,
 unfortunately this one might have been overlooked. I'll investigate
 further.

It hasn't been overlooked, per se. But we know it hasn't been
addressed yet.

The mention I made of it before, (from GUADEC last year), was with
respect to a synthetic benchmark that just drew a single big, focused
button over and over again as fast as it could. And that example
showed quite clearly that post-cairo GTK+ drew that button much more
slowly than pre-cairo GTK+, (and it is definitely the dashed stroke
that is causing the problem).

What hadn't ever been made clear is if real-world applications were
seeing performance problems caused by the dashed stroking. It sounds
like maybe you're on to one of those now.

 Indeed. Just subscribed to that list. In order to avoid confusing
 everyone, I'll stay on this list for now, and might open future
 topics on performance-list (or on the cairo list, if I can make
 myself useful there).

I'm on all three of the lists, and I'd be glad to continue the
discussion wherever you see fit. Within cairo, for example, there's a
custom _cairo_path_fixed_stroke_rectilinear function that would be the
ideal place to throw in support for really fast dashing.

And I don't think it would even be a huge amount of work to fix that
to support the kinds of dashing used in the focus rectangle here.

One thing you could do that might be very useful would be to go into
that function in cairo and remove the following two lines:

if (stroke_style-dash)
return CAIRO_INT_STATUS_UNSUPPORTED;

After you do that, the results won't be correct, (the focus rectangle
will come out solid instead of dashed), but it should give you a
feeling of the upper-bound of the performance benefit you could expect
from adding dash support to this function, (and also confirm if the
dashed stroking is the cause of the problems you're seeing).

And if so, then yes, the cairo list might be the best place to
continue the discussion. In fact, I just decided to pull that list in
with this reply. Please feel free to drop gtk-devel-list from future
replies if we just keep talking about cairo's dashed stroking code.

-Carl


pgpZJ7qQMwjR4.pgp
Description: PGP signature
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-26 Thread Federico Mena Quintero
El lun, 26-03-2007 a las 00:18 +0300, [EMAIL PROTECTED] escribió:

 I tried this idea and changed the GtkTreeDataList to be an array instead of
 linked list (see the attached patch, made against svn head). The original
 testcase (5000x50 model) started up faster (but was still slow), but I didn't 
 do
 any actual measurements yet (let's see tomorrow ;)
 
 I made the following changes:
  * Added dimension/index parameter to many GtkTreeDataList calls (I 
 understood 
that this API was OK to be changed). The GtkTreeDataList is now an array of
n elements instead of single list node.
  * GtkListStore and GtkTreeStore needed similar patches, including:
Simpler get_value/set_value implementation, because we know that the
datalist will contain n elements and they can be indexed easily.
  * Drag'n'drop code now uses simpler _gtk_tree_data_list_copy (I renamed 
_gtk_tree_data_list_node_copy, since we now have more than one element).

Holy crap, you kick ass!

Nicolas, can you get another profile using Markku's patch?

I was looking at the GtkTreeView code and it looks like there are other
places that could get the array treatment.  One place in particular was
the sorting machinery... GtkListStore also uses a GList of information
for the sort headers, and walks the list in g_list_store_compare_func
(!).

  Federico

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-25 Thread markku . vire

Hi,

Lainaus Federico Mena Quintero [EMAIL PROTECTED]:

 Exactly.  GtkListStore is implemented as a GSequence (a splay tree),
 where each node is one row in the list.  Then, the data for the row's
 columns is stored in a linked list (GtkTreeDataList).  You could
 reimplement GtkTreeDataList in terms of an array and get a good speedup
 for *all* uses of GtkListStore (i.e. you'd be replacing a dominant
 O(n^2) for get/set operations in the list store with a simpler O(log n)
 for splay tree lookups, plus the constant time to access a column within
 a node).
 
 Using an array instead of a linked list for GtkTreeDataList is a great
 idea, and we should definitely review a patch for that :)

I tried this idea and changed the GtkTreeDataList to be an array instead of
linked list (see the attached patch, made against svn head). The original
testcase (5000x50 model) started up faster (but was still slow), but I didn't do
any actual measurements yet (let's see tomorrow ;)

I made the following changes:
 * Added dimension/index parameter to many GtkTreeDataList calls (I understood 
   that this API was OK to be changed). The GtkTreeDataList is now an array of
   n elements instead of single list node.
 * GtkListStore and GtkTreeStore needed similar patches, including:
   Simpler get_value/set_value implementation, because we know that the
   datalist will contain n elements and they can be indexed easily.
 * Drag'n'drop code now uses simpler _gtk_tree_data_list_copy (I renamed 
   _gtk_tree_data_list_node_copy, since we now have more than one element).

-Markku-
Index: gtk/gtktreestore.c
===
--- gtk/gtktreestore.c	(revision 17562)
+++ gtk/gtktreestore.c	(working copy)
@@ -386,8 +386,11 @@
 node_free (GNode *node, gpointer data)
 {
   if (node-data)
-_gtk_tree_data_list_free (node-data, (GType*)data);
-  node-data = NULL;
+  {
+GtkTreeStore *store = GTK_TREE_STORE(data);
+_gtk_tree_data_list_free (node-data, store-column_headers, store-n_columns);
+node-data = NULL;
+  }
 
   return FALSE;
 }
@@ -398,7 +401,7 @@
   GtkTreeStore *tree_store = GTK_TREE_STORE (object);
 
   g_node_traverse (tree_store-root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
-		   node_free, tree_store-column_headers);
+		   node_free, tree_store);
   g_node_destroy (tree_store-root);
   _gtk_tree_data_list_header_free (tree_store-sort_list);
   g_free (tree_store-column_headers);
@@ -557,20 +560,17 @@
 {
   GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
   GtkTreeDataList *list;
-  gint tmp_column = column;
 
   g_return_if_fail (column  tree_store-n_columns);
   g_return_if_fail (VALID_ITER (iter, tree_store));
 
   list = G_NODE (iter-user_data)-data;
 
-  while (tmp_column--  0  list)
-list = list-next;
-
   if (list)
 {
   _gtk_tree_data_list_node_to_value (list,
 	 tree_store-column_headers[column],
+	 column,
 	 value);
 }
   else
@@ -719,8 +719,6 @@
 			   gboolean  sort)
 {
   GtkTreeDataList *list;
-  GtkTreeDataList *prev;
-  gint old_column = column;
   GValue real_value = {0, };
   gboolean converted = FALSE;
   gboolean retval = FALSE;
@@ -748,61 +746,23 @@
   converted = TRUE;
 }
 
-  prev = list = G_NODE (iter-user_data)-data;
-
-  while (list != NULL)
+  list = G_NODE (iter-user_data)-data;
+  if (G_UNLIKELY(list == NULL))
 {
-  if (column == 0)
-	{
+  G_NODE (iter-user_data)-data = list = 
+  _gtk_tree_data_list_alloc (tree_store-n_columns);
+}
+
 	  if (converted)
-	_gtk_tree_data_list_value_to_node (list, real_value);
+	_gtk_tree_data_list_value_to_node (list, column, real_value);
 	  else
-	_gtk_tree_data_list_value_to_node (list, value);
+	_gtk_tree_data_list_value_to_node (list, column, value);
 	  retval = TRUE;
 	  if (converted)
 	g_value_unset (real_value);
   if (sort  GTK_TREE_STORE_IS_SORTED (tree_store))
-gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
+gtk_tree_store_sort_iter_changed (tree_store, iter, column, TRUE);
 	  return retval;
-	}
-
-  column--;
-  prev = list;
-  list = list-next;
-}
-
-  if (G_NODE (iter-user_data)-data == NULL)
-{
-  G_NODE (iter-user_data)-data = list = _gtk_tree_data_list_alloc ();
-  list-next = NULL;
-}
-  else
-{
-  list = prev-next = _gtk_tree_data_list_alloc ();
-  list-next = NULL;
-}
-
-  while (column != 0)
-{
-  list-next = _gtk_tree_data_list_alloc ();
-  list = list-next;
-  list-next = NULL;
-  column --;
-}
-
-  if (converted)
-_gtk_tree_data_list_value_to_node (list, real_value);
-  else
-_gtk_tree_data_list_value_to_node (list, value);
-  
-  retval = TRUE;
-  if (converted)
-g_value_unset (real_value);
-
-  if (sort  GTK_TREE_STORE_IS_SORTED (tree_store))
-gtk_tree_store_sort_iter_changed (tree_store, iter, old_column, TRUE);
-
-  return retval;
 }
 
 /**
@@ 

Re: ideas on improving the performance of gtk_tree_view

2007-03-23 Thread Kristian Rietveld
On Thu, Mar 22, 2007 at 08:18:14PM +0200, Tommi Komulainen wrote:
 On 3/22/07, Kalle Vahlman [EMAIL PROTECTED] wrote:
  2007/3/22, Yevgen Muntyan [EMAIL PROTECTED]:
  
   IIRC reusing single cell renderer in multiple columns was declared
   broken and unsupported (because it was broken). Is this correct?

Yes, a single cell renderer is not supposed to be used in multiple
columns.  Of couse you might get lucky and it works more or less.

  Maybe there are specific cell renderers that are broken?
 
 As I understood it, it is broken if you do not set the same set of
 attributes on each column. Try mapping text and font weight on one
 column, and just text on another column and see what happens ;-)

That's one really good example of how things will break.  And you also
already provided a way to work around it :)  For the record I am not
planning on fixing any new bugs which show up because of using a single cell
renderer in multiple columns.  Maybe we should guard for reusing a cell
renderer multiple times in a later version of GTK+.


regards,

-kris.
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-23 Thread Kalle Vahlman
2007/3/23, Kristian Rietveld [EMAIL PROTECTED]:
 On Thu, Mar 22, 2007 at 08:18:14PM +0200, Tommi Komulainen wrote:
  On 3/22/07, Kalle Vahlman [EMAIL PROTECTED] wrote:
   2007/3/22, Yevgen Muntyan [EMAIL PROTECTED]:
   
IIRC reusing single cell renderer in multiple columns was declared
broken and unsupported (because it was broken). Is this correct?

 Yes, a single cell renderer is not supposed to be used in multiple
 columns.  Of couse you might get lucky and it works more or less.

   Maybe there are specific cell renderers that are broken?
 
  As I understood it, it is broken if you do not set the same set of
  attributes on each column. Try mapping text and font weight on one
  column, and just text on another column and see what happens ;-)

 That's one really good example of how things will break.  And you also
 already provided a way to work around it :)  For the record I am not
 planning on fixing any new bugs which show up because of using a single cell
 renderer in multiple columns.  Maybe we should guard for reusing a cell
 renderer multiple times in a later version of GTK+.

And at minimum update the docs ASAP to note this. The paragraph I
pasted had me at least thinking it doesn't matter at all where the
renderer is used...

-- 
Kalle Vahlman, [EMAIL PROTECTED]
Powered by http://movial.fi
Interesting stuff at http://syslog.movial.fi
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-23 Thread Federico Mena Quintero
El jue, 22-03-2007 a las 16:55 +0100, Nicolas Setton escribió:

Hi, Nicolas,

Thanks for taking the time to profile this!

 Consider the subprogram attached. It shows a simple tree_view  
 displaying a list_store (5000 columns and 50 rows containing  
 integers). The display performance is very poor: when displaying the  
 last columns, the vertical scollbar takes between 5 and 10 seconds to  
 respond.

Two things:

1. Yes, we abuse lists here and there.  The performance would definitely
be better with an array.  This is reasonably easy to do, since the
changes are internal and self-contained in GtkListStore and
GtkTreeDataList.

2. You just created a user interface disaster :)  How are your users
going to be able to jump to the right column?

 So, it seems that we spend most of our time traversing the list of  
 columns. Note that this explains why a tree of 5000 columns x 50 rows  
 has such bad performance compared to a tree of 50 columns x 5000 rows.
 
 First suggestion: we'd be better off in this subprogram if the data  
 was implemented as an array instead of as a linked list.

Exactly.  GtkListStore is implemented as a GSequence (a splay tree),
where each node is one row in the list.  Then, the data for the row's
columns is stored in a linked list (GtkTreeDataList).  You could
reimplement GtkTreeDataList in terms of an array and get a good speedup
for *all* uses of GtkListStore (i.e. you'd be replacing a dominant
O(n^2) for get/set operations in the list store with a simpler O(log n)
for splay tree lookups, plus the constant time to access a column within
a node).

Using an array instead of a linked list for GtkTreeDataList is a great
idea, and we should definitely review a patch for that :)

 I'm not familiar with this area yet, so I'm puzzled: is the call to  
 gtk_tree_view_column_cell_set_cell_data really needed for the  
 purposes of gtk_tree_view_bin_expose, or is it just needed for the  
 call to gtk_tree_view_has_special_cell?
 
 In any case, I suggest we cache this - probably there is no need to  
 do it in every expose call, only after the model data has changed.

It absolutely needs to be called for each row, so that the tree view can
know how to display the focus rectangle (a cell-wide rectangle for
editable/activatable cells, a row-wide rectangle for cold cells).

The has_special_cell condition is particular to each row, so the
benefits of caching it (say, in the GtkRBTree) would only serve for
multiple exposes of the same unchanging data.  But since one needs to
walk the entire row to paint it, anyway, you'd simply be doing one walk
instead of two.  But the main problem is getting the cell's data from
the model (i.e. walking the GtkTreeDataList) - fix that, and the problem
with has_special_cell may simply disappear.

Hacking GtkListStore/GtkTreeDataList to use an array for the row data
should take one or two afternoons, and it would benefit all trees, not
just your huge one.  Wanna do it for fame and glory? :)

[This would also save memory, since you avoid having GSlice-induced
padding in each GtkTreeDataList structure and you also save a pointer
per node.  I'd love to see actual numbers for this.]

  Federico

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-23 Thread Federico Mena Quintero
El vie, 23-03-2007 a las 23:19 +0100, Michael Natterer escribió:

 I would rather say we absolutely don't abuse lists here. There is no
 significant difference between list and array for a couple of items
 (say  50 items). The only abuse I see is creating a treeview with
 5000 columns. The widget is simply not made for that. It would be
 the same as optimizing GtkVBox for 5000 children and asking for
 the internal list being replaced by an array.

So, a few things:

* 5000 columns is definitely abusing the *user*.  Who cares about the
toolkit.

* A tree row has an immutable number of columns; their datums are of
known sizes.  This screams array.

* An array would give you less memory overhead from allocator padding,
better cache locality, less pressure on the allocator, and constant-time
access to the columns.  I bet that it will also require less code than a
list :)

 What GTK+ needs here is a *sheet* widget, something that is optimized
 for organizing two-dimensional data in an efficient way. Hacking up
 GtkTreeView for insane use cases does no good whatsoever.

Yes, we definitely need a sheet widget.  I don't know why people don't
just write one, or revive the old one.  Maybe they are scared that it
doesn't do enough for a spreadsheet --- but people are not building
spreadsheets; they just want to display simple tabular data.

 P.S.: I do not say that optimizing treeview is a bad idea, I would
   just find it very unfortunate to waste developer resources
   in order to optimize use cases like this.

I'd rather not discourage people who are actually bothering to profile
our shitty code --- they don't come along very often.

  Federico

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-23 Thread Germán Poó Caamaño
On Fri, 2007-03-23 at 17:35 -0600, Federico Mena Quintero wrote:
 El vie, 23-03-2007 a las 23:19 +0100, Michael Natterer escribió:
 [...]
  What GTK+ needs here is a *sheet* widget, something that is optimized
  for organizing two-dimensional data in an efficient way. Hacking up
  GtkTreeView for insane use cases does no good whatsoever.
 
 Yes, we definitely need a sheet widget.  I don't know why people don't
 just write one, or revive the old one.  Maybe they are scared that it
 doesn't do enough for a spreadsheet --- but people are not building
 spreadsheets; they just want to display simple tabular data.

Such widget was written a while ago by Lorenzo Gil Sánchez
(Gazpacho's author):
http://www.sicem.biz/personal/lgs/projects/gtkgrid/view_project

But the discussion take here when it was proposed, wasn't very
stimulating so far:
http://mail.gnome.org/archives/gtk-devel-list/2004-April/msg00137.html

-- 
Germán Poó Caamaño
Concepción - Chile

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Nicolas Setton
This describes an idea to improve the display performance of the  
tree_views, based on the sources of gtk+-2.10.11, and suggests  
possible solutions.



Consider the subprogram attached. It shows a simple tree_view  
displaying a list_store (5000 columns and 50 rows containing  
integers). The display performance is very poor: when displaying the  
last columns, the vertical scollbar takes between 5 and 10 seconds to  
respond.


Preliminary note: a tree of 50 columns and 5000 rows displays better  
performance (scrollbars take between 0 and 1 seconds to respond).


Using the Apple Shark profiler gave me the following tree showing  
where the time is spent while simply scrolling the scrollbar. In this  
tree, line N+1 calls line N.


SelfTotal   Library

0.0%80.3%   bigtree main
0.0%80.3%   libgtk-x11-2.0.0.dylib  gtk_main
0.0%80.3%   libglib-2.0.0.dylib g_main_loop_run 
0.0%80.3%   libglib-2.0.0.dylib g_main_context_iterate  
0.0%80.3%   libglib-2.0.0.dylib g_main_context_dispatch 
0.0%80.3%   libglib-2.0.0.dylib g_main_dispatch 
0.0%79.8%   libglib-2.0.0.dylib g_idle_dispatch 
0.0%79.8%   libgdk-x11-2.0.0.dylib  gdk_window_update_idle  
0.0%79.8%   libgdk-x11-2.0.0.dylib  gdk_window_process_all_updates  
0.0%79.8%   libgdk-x11-2.0.0.dylib  
gdk_window_process_updates_internal 
0.0%79.8%   libgtk-x11-2.0.0.dylib  gtk_main_do_event   
0.0%79.8%   libgtk-x11-2.0.0.dylib  gtk_widget_send_expose  
0.0%79.8%   libgtk-x11-2.0.0.dylib  gtk_widget_event_internal   
0.0%79.8%   libgobject-2.0.0.dylib  g_signal_emit   
0.0%79.8%   libgobject-2.0.0.dylib  g_signal_emit_valist
0.0%79.8%   libgobject-2.0.0.dylib  signal_emit_unlocked_R  
0.0%79.8%   libgobject-2.0.0.dylib  g_closure_invoke
0.0%79.8%   libgobject-2.0.0.dylib  g_type_class_meta_marshal   
0.0%79.8%   libgtk-x11-2.0.0.dylib  _gtk_marshal_BOOLEAN__BOXED 
0.0%79.8%   libgtk-x11-2.0.0.dylib  gtk_tree_view_expose
0.2%79.6%   libgtk-x11-2.0.0.dylib  gtk_tree_view_bin_expose
	0.4%	26.4%	libgtk-x11-2.0.0.dylib	 
gtk_tree_view_column_cell_set_cell_data	

0.0%18.4%   libgtk-x11-2.0.0.dylib  gtk_tree_model_get_value
17.5%   18.0%   libgtk-x11-2.0.0.dylib  gtk_list_store_get_value

I have two comments to make about this tree:

  A) it seems strange that 18% of the time is spent in  
gtk_list_store_get_value.


  B) it seems very strange that gtk_tree_view_bin_expose calls  
gtk_tree_view_column_cell_set_cell_data.


Investigating further in the direction given by comment A), I saw  
that the following lines in gtkliststore.c were consuming the biggest  
amount of time:


SelfTotal   LineCode

451 static void 
452 gtk_list_store_get_value (GtkTreeModel 
*tree_model, 
453   GtkTreeIter  *iter,   

454   gint  column, 

455   GValue   *value)  

0.0%0.1%456 {   
457   GtkListStore *list_store = (GtkListStore *) 
tree_model;   
458   GtkTreeDataList *list;
459   gint tmp_column = column; 
460 
0.0%0.0%461   g_return_if_fail (column  
list_store-n_columns);  
0.0%0.4%462   g_return_if_fail (VALID_ITER (iter, 
list_store)); 
463 
0.0%0.4%464   list = _gtk_sequence_ptr_get_data 
(iter-user_data);   
465 
53.2%   51.8%   466   while (tmp_column--  0  list)  
 
46.5%   45.3%   467 list = list-next;   
468 
0.0%0.0%469   if (list == NULL) 
470 g_value_init (value, 
list_store-column_headers[column]);
471   else  
0.1%1.9%472 _gtk_tree_data_list_node_to_value (list,

473
list_store-column_headers[column],   
474 

Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Kalle Vahlman
2007/3/22, Nicolas Setton [EMAIL PROTECTED]:
[snip]
 So, it seems that we spend most of our time traversing the list of
 columns. Note that this explains why a tree of 5000 columns x 50 rows
 has such bad performance compared to a tree of 50 columns x 5000 rows.

Your test program is also creating 4950 cellrenderers more in that
case, while the extra rows are for free in that sense (ie. same
amount of data items stored, but no extra cellrenderers). See below
for more on this.

 First suggestion: we'd be better off in this subprogram if the data
 was implemented as an array instead of as a linked list.

I guess this could be valid in any case...

 Let's turn now to comment B). Why is gtk_tree_view_bin_expose calling
 gtk_tree_view_column_cell_set_cell_data ?
[snap]
 I'm not familiar with this area yet, so I'm puzzled: is the call to
 gtk_tree_view_column_cell_set_cell_data really needed for the
 purposes of gtk_tree_view_bin_expose, or is it just needed for the
 call to gtk_tree_view_has_special_cell?

It _is_ really needed for expose, since GtkCellRenderers are not tied
to the data it's rendering:


The primary use of a GtkCellRenderer is for drawing a certain
graphical elements on a GdkDrawable. Typically, one cell renderer is
used to draw many cells on the screen. To this extent, it isn't
expected that a CellRenderer keep any permanent state around. Instead,
any state is set just prior to use using GObjects property system.
Then, the cell is measured using gtk_cell_renderer_get_size().
Finally, the cell is rendered in the correct location using
gtk_cell_renderer_render().

http://developer.gnome.org/doc/API/2.0/gtk/GtkCellRenderer.html#id3190590

 In any case, I suggest we cache this - probably there is no need to
 do it in every expose call, only after the model data has changed.

...so it isn't really feasible to cache the renderer state. The good
news learned from the above is that if you simply move the renderer
creation outside the for loop, you'll get the same functionality but
without 4999 extra cellrenderers in memory :)

 To sum up (thanks for reading me), would you accept a patch along
 those lines?

I let Kris and others comment on the array thing, but it would be
interesting to re-measure and see how much the 4999 cellrenderers were
affecting the performance (not much I guess, but it should use a fair
amount less memory then).

Anyway, nice test case to hack on :)

-- 
Kalle Vahlman, [EMAIL PROTECTED]
Powered by http://movial.fi
Interesting stuff at http://syslog.movial.fi
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Kristian Rietveld
On Thu, Mar 22, 2007 at 04:55:30PM +0100, Nicolas Setton wrote:
 Consider the subprogram attached. It shows a simple tree_view  
 displaying a list_store (5000 columns and 50 rows containing  
 integers). The display performance is very poor: when displaying the  
 last columns, the vertical scollbar takes between 5 and 10 seconds to  
 respond.
 
 Preliminary note: a tree of 50 columns and 5000 rows displays better  
 performance (scrollbars take between 0 and 1 seconds to respond).

There is a really simple answer to this: GtkTreeView is not a table, it
was not designed to handle views like this with  50 columns.

 First suggestion: we'd be better off in this subprogram if the data  
 was implemented as an array instead of as a linked list.

That would only help GtkListStore, other models might need different
solutions.  There are also multiple places in GtkTreeView which all
assume a reasonable amount of columns (I would say  50), I am not sure
if all this is worth changing at all.

 I'm not familiar with this area yet, so I'm puzzled: is the call to  
 gtk_tree_view_column_cell_set_cell_data really needed for the  
 purposes of gtk_tree_view_bin_expose, or is it just needed for the  
 call to gtk_tree_view_has_special_cell?

It is needed to make the call to gtk_tree_view_has_special_cell() return
a proper and correct result.  This correct result is required in order
to make the key navigation behave properly.

 In any case, I suggest we cache this - probably there is no need to  
 do it in every expose call, only after the model data has changed.

This is something which cannot really be cached, CellDataFuncs can also
influence this value, and CellDataFuncs can depend on more data than
just the data found in the model.


regards,

-kris.
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Yevgen Muntyan
Kalle Vahlman wrote:
 2007/3/22, Nicolas Setton [EMAIL PROTECTED]:
   
[snip]
 In any case, I suggest we cache this - probably there is no need to
 do it in every expose call, only after the model data has changed.
 

 ...so it isn't really feasible to cache the renderer state. The good
 news learned from the above is that if you simply move the renderer
 creation outside the for loop, you'll get the same functionality but
 without 4999 extra cellrenderers in memory :)
   
IIRC reusing single cell renderer in multiple columns was declared
broken and unsupported (because it was broken). Is this correct?

Yevgen

___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Kalle Vahlman
2007/3/22, Yevgen Muntyan [EMAIL PROTECTED]:
 Kalle Vahlman wrote:
  2007/3/22, Nicolas Setton [EMAIL PROTECTED]:
 
 [snip]
  In any case, I suggest we cache this - probably there is no need to
  do it in every expose call, only after the model data has changed.
 
 
  ...so it isn't really feasible to cache the renderer state. The good
  news learned from the above is that if you simply move the renderer
  creation outside the for loop, you'll get the same functionality but
  without 4999 extra cellrenderers in memory :)
 
 IIRC reusing single cell renderer in multiple columns was declared
 broken and unsupported (because it was broken). Is this correct?

It worked amazingly well for being broken ;)

Maybe there are specific cell renderers that are broken?

-- 
Kalle Vahlman, [EMAIL PROTECTED]
Powered by http://movial.fi
Interesting stuff at http://syslog.movial.fi
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Tommi Komulainen
On 3/22/07, Kalle Vahlman [EMAIL PROTECTED] wrote:
 2007/3/22, Yevgen Muntyan [EMAIL PROTECTED]:
 
  IIRC reusing single cell renderer in multiple columns was declared
  broken and unsupported (because it was broken). Is this correct?

 It worked amazingly well for being broken ;)

 Maybe there are specific cell renderers that are broken?

As I understood it, it is broken if you do not set the same set of
attributes on each column. Try mapping text and font weight on one
column, and just text on another column and see what happens ;-)


-- 
Tommi Komulainen [EMAIL PROTECTED]
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list


Re: ideas on improving the performance of gtk_tree_view

2007-03-22 Thread Nicolas Setton
[Thanks everyone for your answers]

 There is a really simple answer to this: GtkTreeView is not a table,
 it was not designed to handle views like this with  50 columns.

I'm not sure I understand this part: should I use a gtk_table to  
display this kind of data? What is the preferred way to display this  
kind of information (5000 columns x 50 rows) in Gtk+? The GtkTreeView  
seemed the best approach to me.

Moreover, the GtkTreeView 'almost' supports this, so I think it would  
be a shame to simply throw down our weapons so soon! See below for  
suggestions.

 That would only help GtkListStore, other models might need different
 solutions.  There are also multiple places in GtkTreeView which all
 assume a reasonable amount of columns (I would say  50), I am not  
 sure
 if all this is worth changing at all.

The GtkTreeStore would also benefit from that, but I agree with you,  
it might not be worth changing.

 I'm not familiar with this area yet, so I'm puzzled: is the call to
 gtk_tree_view_column_cell_set_cell_data really needed for the
 purposes of gtk_tree_view_bin_expose, or is it just needed for the
 call to gtk_tree_view_has_special_cell?

 It is needed to make the call to gtk_tree_view_has_special_cell()  
 return
 a proper and correct result.  This correct result is required in order
 to make the key navigation behave properly.

This gives me an idea.

Proposal (1): we give the user the possibility (through a property,  
for instance) to deactivate keyboard navigation, in exchange for an  
enormous gain of performance for big trees.

 In any case, I suggest we cache this - probably there is no need to
 do it in every expose call, only after the model data has changed.

 This is something which cannot really be cached, CellDataFuncs can  
 also
 influence this value, and CellDataFuncs can depend on more data than
 just the data found in the model.

This gives me another idea, which I think is better than Proposal (1).

Proposal (2): we give the user the possibility to tell the tree view  
that the only way the data will change is through the model. When the  
tree view is guaranteed this, it executes the loop on  
gtk_tree_view_column_cell_set_cell_data only once in each model  
change, and not once in every expose.

Note that, when you deactivate this loop, you get very fluid response  
even for the 5000 columns tree. We're looking at something like 5000%  
performance increase, and this the kind of users would get from  
Proposal (1) or Proposal (2).

What do you think?

Nicolas
___
gtk-devel-list mailing list
gtk-devel-list@gnome.org
http://mail.gnome.org/mailman/listinfo/gtk-devel-list