After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 94718 - Graying of menu/toolbars eats lots of cpu
Graying of menu/toolbars eats lots of cpu
Status: RESOLVED OBSOLETE
Product: Gnumeric
Classification: Applications
Component: GUI
git master
Other Linux
: Normal normal
: ---
Assigned To: Morten Welinder
Morten Welinder
Depends on:
Blocks:
 
 
Reported: 2002-10-02 20:42 UTC by T'aZ
Modified: 2009-09-09 02:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
test case isolating the gtk+ toolbar code (5.25 KB, text/plain)
2003-06-03 20:32 UTC, Mike Uber Otriz
Details
Makefile for the lazy (335 bytes, text/plain)
2003-06-03 20:33 UTC, Mike Uber Otriz
Details
updated version of the test file (5.71 KB, text/plain)
2003-06-09 19:57 UTC, Chema Celorio
Details

Description T'aZ 2002-10-02 20:42:56 UTC
when i type in a cell , the menu and the toolbars become grayed out , and
they get back to normal when i've finished typing in that cell.
the problem is that this operation (graying the toolbars ..) takes a lot of
cpu on my slow machine (200mhz)
so there is a little annoying lag between the moment i start typing ant the
moment i see that in the cell
idem between the moment i've finished typing and the moment i see the newly
selected cell

this is maybe a performance problem of gtk or such , i donno

maybe an option (or an argument to give during the compilation) to simply
not gray out ?
Comment 1 Jody Goldberg 2002-10-03 02:39:46 UTC
Gnumeric has absolutely nothing to do with this.  The entire process is handled
by the sensitizing and de-sensitizing of the toolbar widget.  I have definitely
seen a major performance degredation in gtk-2.0 vs 1.2.
Comment 2 Owen Taylor 2002-10-03 18:09:29 UTC
"GTK+ is slow" is not a useful bug report.

GTK+-2.0 is slower than GTK+-1.2 in various areas. Yes.
It does a lot more too.

Without detailed information about _what_ is slow, and
suggestions about speeding it up, there really isn't
anything concrete that can be done, so it isn't useful
to keep this open.


Comment 3 Morten Welinder 2002-10-03 18:48:16 UTC
Re-opening to gather more info.
Comment 4 Morten Welinder 2002-10-03 18:48:49 UTC
Mine, mine, mine.
Comment 5 Jody Goldberg 2002-10-03 19:58:15 UTC
Owen, that is an overstatement.  The report is quite clear and has been made
before.  Desensitizing toolbar buttons in gtk2 uses significantly more
bandwidth than gtk-1.2.  Federico has commented that he knows the source of the
slowdown in GtkImage.  I understand that you are busy, but from my perspective
as an app with lots of toolbar item this is a significant performance
regression.  How can we make the report more specific ?  In the past I've done
xmon logs, but all that verifies is that lots of images get sent when the
transition takes place.
Comment 6 Morten Welinder 2002-10-03 20:20:08 UTC
There's more to it.  I am running Gnumeric remotely, and just typing
"a" (which desentisises the toolbars) causes about 100 writes to the
X display.

Quantify reports (for just typing "a", ignoring time spent in system
calls):

 10.30%   gdk_keymap_get_entries_for_keyval
  7.56%   g_type_check_instance_cast
  6.12%   gdk_pixbuf_saturate_and_pixelate
  6.02%   g_type_check_instance_is_a
  2.83%   g_type_value_table_peek
  2.72%   composite_0888
  2.63%   mutex_unlock
  2.24%   signal_emit_unlocked_R
  2.16%   .umul
  2.13%   _XGetPixel32
  2.12%   g_signal_emit_valist
  1.74%   strcmp
  1.70%   g_hash_table_lookup
  1.68%   g_type_is_a
  1.53%   mutex_lock
  1.48%   _XPutPixel32
  1.45%   Letext[libgobject-2.0.so.0.100.0/361]
  1.43%   g_type_check_is_value_type
  1.26%   g_type_check_value
  1.10%   _free_unlocked


Cummulative times are...

...
 100.00%   g_main_context_iterate
  98.78%   g_main_context_dispatch
  98.75%   g_main_dispatch
  91.42%   gtk_main_do_event
  90.82%   g_signal_emit_valist
  90.02%   gtk_signal_emit
  89.05%   gtk_widget_event_internal
  87.84%   signal_emit_unlocked_R
  86.90%   g_closure_invoke
  86.68%   g_type_class_meta_marshal
  85.37%   _gtk_marshal_BOOLEAN__BOXED
  56.84%   gdk_event_dispatch
  52.16%   gtk_widget_event
  48.60%   gtk_propagate_event
  41.80%   g_idle_dispatch
  39.13%   gdk_window_process_all_updates
  39.07%   gdk_window_process_updates_internal
  38.95%   gtk_container_idle_sizer
  37.59%   gtk_container_forall
  36.96%   gtk_widget_send_expose
  34.73%   bonobo_window_key_press_event
  34.73%   gtk_window_key_press_event
  34.04%   gtk_bin_forall
  33.09%   gtk_container_expose
  33.07%   gtk_container_propagate_expose
  33.05%   gtk_container_expose_child
  32.16%   gtk_im_context_filter_keypress
  32.16%   gtk_im_multicontext_filter_keypress
  32.16%   gnm_canvas_key_press
  32.16%   gtk_im_context_simple_filter_keypress
  32.15%   no_sequence_matches
  32.15%   gtk_im_context_simple_commit_char
  32.15%   g_signal_emit_by_name
  32.14%   g_cclosure_marshal_VOID__STRING
  32.14%   gtk_im_multicontext_commit_cb
  32.13%   gnm_canvas_commit_cb
  31.98%   wbcg_edit_start
  31.81%   wb_control_edit_set_sensitive
  31.81%   wbcg_edit_set_sensitive
  31.38%   wbcg_menu_state_sensitivity
  31.38%   bonobo_ui_component_set_prop
  31.37%   impl_set_prop
  31.37%   Bonobo_UIContainer_setAttr
  31.37%   impl_Bonobo_UIContainer_setAttr
  31.37%   bonobo_ui_engine_xml_set_prop
  31.31%   bonobo_ui_engine_update
  28.88%   bonobo_dock_item_expose
  28.09%   bonobo_dock_item_forall
  27.91%   impl_expose_event[libbonoboui-2.so.0.0.0/1040]
  27.17%   gtk_box_forall
  26.17%   bonobo_ui_engine_update_node
  26.06%   do_sync
  25.32%   bonobo_ui_engine_sync
  23.32%   bonobo_ui_sync_state
  23.30%   impl_bonobo_ui_sync_toolbar_state
  22.18%   gtk_button_expose
  20.12%   gtk_image_expose
  16.78%   bonobo_ui_toolbar_button_item_set_label
  16.75%   impl_set_label[libbonoboui-2.so.0.0.0/923]
  12.61%   g_signal_emit
  12.39%   _gtk_key_hash_lookup
  12.38%   key_hash_get_keycode_hash
  12.37%   key_hash_insert_entry
  12.00%   gdk_keymap_get_entries_for_keyval
  10.87%   gdk_draw_pixbuf
  10.62%   gdk_window_draw_pixbuf
  10.45%   bonobo_window_key_release_event
  10.45%   gtk_window_key_release_event
  10.44%   gdk_pixmap_draw_pixbuf
  10.41%   gnm_canvas_key_release
  10.41%   gnm_simple_canvas_key_release
  10.41%   gnome_canvas_key
  10.41%   gdk_drawable_real_draw_pixbuf
  10.39%   gtk_widget_real_key_release_event
  10.39%   _gtk_bindings_activate_event
   8.96%   gtk_widget_render_icon
   8.81%   gtk_style_render_icon
   8.80%   gtk_default_render_icon
   8.79%   gtk_icon_set_render_icon
   8.45%   set_label
   8.45%   layout_pixmap_and_label
   8.21%   gtk_box_pack_end
   7.92%   g_type_check_instance_cast
   6.93%   g_object_notify
   6.50%   gtk_widget_destroy
   6.48%   gtk_object_destroy
   6.46%   g_object_run_dispose
   6.38%   g_object_notify_dispatcher
   6.37%   g_object_dispatch_properties_changed
   6.34%   g_type_check_instance_is_a
   6.15%   gdk_pixbuf_saturate_and_pixelate
   6.05%   gtk_widget_dispose
   5.25%   gtk_widget_set_sensitive
   5.10%   _gdk_drawable_copy_to_image
   5.08%   g_value_set_instance
   5.05%   _gdk_x11_copy_to_image
   4.97%   gtk_widget_propagate_state
   4.94%   state_update_new
   4.90%   update_commands_state
   4.79%   make_updates_for_command
   4.77%   gtk_toggle_button_expose
   4.76%   XGetSubImage
   4.62%   gtk_widget_set_parent
   4.61%   g_type_value_table_peek
   4.58%   gtk_window_expose
   4.47%   _XSetImage
   4.41%   impl_forall
   4.31%   g_object_unref
   4.27%   g_hash_table_lookup
   4.03%   g_value_type_compatible
   4.00%   g_cclosure_marshal_VOID__VOID
...


In terms of calls we have...

296700   .umul
198932   Letext[libgobject-2.0.so.0.100.0/361]
 60052   mutex_unlock
 60052   mutex_lock
 48832   g_type_check_instance_cast
 43225   g_type_check_instance_is_a
 38633   g_type_value_table_peek
 28371   Letext[libgobject-2.0.so.0.100.0/462]
 25433   _XPutPixel32
 25433   _XGetPixel32
 24886   unknown_static_function[libgtk-x11-2.0.so.0.100.0/5443]
 21427   Letext[libglib-2.0.so.0.100.0/442]
 20956   unknown_static_function[libgobject-2.0.so.0.100.0/68]
 20537   g_type_check_is_value_type
 17283   strcmp
 16880   unknown_static_function[libgtk-x11-2.0.so.0.100.0/2627]
 15718   gtk_object_get_type
 15665   gtk_widget_get_type
 15042   unknown_static_function[libglib-2.0.so.0.100.0/219]
 14728   g_type_check_value
 14520   .urem
 14319   Letext[libglib-2.0.so.0.100.0/748]
 13505   g_type_is_a
 13022   g_hash_table_lookup
  9932   Letext[libglib-2.0.so.0.100.0/121]
  9824   g_free
  9722   _malloc_unlocked
  9360   malloc
  9304   param_spec_pool_equals
  8487   cleanfree
  8460   unknown_static_function[libgobject-2.0.so.0.100.0/286]
  8334   g_str_equal
  8120   _free_unlocked
  8026   free
  8016   signal_key_cmp
  7943   Letext[libgdk-x11-2.0.so.0.100.0/62]
  7782   boxed_nodes_cmp
  7744   _smalloc
  7261   g_value_unset
  7261   g_value_init
  7043   Letext[libgobject-2.0.so.0.100.0/26]
  6961   realfree
  6676   g_object_unref
  6581   g_object_ref
  6569   g_type_check_instance
  6390   g_value_type_compatible
  6353   unknown_static_function[libgdk-x11-2.0.so.0.100.0/789]
  6272   get_attr
  6257   g_malloc
  6139   g_static_rw_lock_reader_lock
  6139   g_static_rw_lock_reader_unlock
  6132   g_value_object_free_value
  5833   unknown_static_function[libgdk_pixbuf-2.0.so.0.100.0/1]
  5784   unknown_static_function[libgobject-2.0.so.0.100.0/6]
  5746   g_direct_hash
  5060   bonobo_ui_node_get_data
  5028   Letext[libgdk-x11-2.0.so.0.100.0/152]
  5019   param_spec_pool_hash
  4832   .udiv
  4754   g_type_parent
  4585   _gdk_gc_x11_get_type
  4387   memset
  4323   Letext[libgdk-x11-2.0.so.0.100.0/440]
  4050   gdk_drawable_get_type
  3887   g_datalist_id_get_data
  3832   unknown_static_function[libgtk-x11-2.0.so.0.100.0/766]
  3814   unknown_static_function[libgdk-x11-2.0.so.0.100.0/392]
  3735   g_value_object_peek_pointer
  3735   g_value_peek_pointer
  3574   unknown_static_function[libgobject-2.0.so.0.100.0/583]
  3523   calloc
  3476   g_malloc0
  3471   gdk_gc_get_type
  3403   g_type_check_value_holds
  3347   Letext[libgobject-2.0.so.0.100.0/135]
  3267   g_str_hash
  3158   Letext[libglib-2.0.so.0.100.0/334]
  3125   g_closure_unref
  3109   gdk_window_object_get_type
  3090   Letext[libgdk-x11-2.0.so.0.100.0/948]
  3085   Letext[libgdk-x11-2.0.so.0.100.0/707]
  3068   handler_lists_cmp
  3066   g_value_object_init
  3066   g_value_object_collect_value
  3024   gdk_pixbuf_get_n_channels
  2956   Letext[libgdk-x11-2.0.so.0.100.0/605]
  2847   _gdk_drawable_impl_x11_get_type
  2812   g_signal_emit_valist
  2812   g_value_set_instance
  2812   signal_emit_unlocked_R
  2808   Letext[libgobject-2.0.so.0.100.0/581]
  2741   g_closure_invoke
  2740   gtk_container_get_type
  2637   _gdk_screen_x11_get_type
  2610   _gdk_display_x11_get_type
  2606   Letext[libbonoboui-2.so.0.0.0/1092]
  2588   boxed_proxy_value_free
  2540   unknown_static_function[libgtk-x11-2.0.so.0.100.0/5631]
  2530   bonobo_ui_xml_get_data
  2415   g_type_class_meta_marshal
  2322   g_datalist_id_set_data_full
  2281   memcpy
  2245   gtk_window_get_type
  2109   g_type_check_class_cast
  2105   unknown_static_function[libgtk-x11-2.0.so.0.100.0/3257]
  2012   Letext[libbonoboui-2.so.0.0.0/802]
  1921   g_quark_from_string
  1859   g_list_alloc
  1856   gtk_signal_emit
  1810   .div
  1666   bonobo_ui_node_get_attr_by_id
  1568   bonobo_ui_sync_get_type
  1557   Letext[libbonoboui-2.so.0.0.0/954]
  1497   unknown_static_function[libgtk-x11-2.0.so.0.100.0/1895]
  1430   strlen
  1402   g_value_set_boolean
  1394   g_strdup
  1383   style_property_values_cmp
  1294   boxed_proxy_collect_value
  1294   boxed_proxy_value_init
  1290   g_list_free_1
  1278   Letext[libgdk-x11-2.0.so.0.100.0/42]
  1264   value_param_free_value
  1253   bonobo_ui_node_next
  1213   unknown_static_function[libgdk-x11-2.0.so.0.100.0/1010]
  1202   Letext[libgtk-x11-2.0.so.0.100.0/1588]
  1194   unknown_static_function[libgtk-x11-2.0.so.0.100.0/3377]
  1189   unknown_static_function[libgnomecanvas-2.so.0.0.0/257]
  1172   floor
  1148   gtk_widget_get_toplevel
  1129   gdk_display_get_type
  1114   g_slist_alloc
  1104   g_slist_prepend
  1098   Letext[libgdk-x11-2.0.so.0.100.0/266]
  1067   unknown_static_function[libglib-2.0.so.0.100.0/2]
  1053   gdk_region_destroy
  1029   gtk_widget_unref
  1029   gtk_widget_ref
  1024   bonobo_ui_node_children
  1023   g_value_get_boolean

(Letext is a gcc bug.  You get to guess the real name...)


Comment 7 Federico Mena Quintero 2002-10-03 20:22:50 UTC
GtkImage does the following on every expose:

1. Get a pixbuf from somewhere -- if it is a stock icon, it renders it
from the style.

2. gdk_pixbuf_render_to_drawable().

This is extremely wasteful.  It should keep a cache of rendered
pixmaps, pre-composited and everything, and just use them from the
server from the second expose thereon.

Bonobo 1.4 has a cache for this kind of stuff -- it yielded important
speedups, particularly for the remote X server case.
Comment 8 Owen Taylor 2002-10-03 22:14:09 UTC
"slower than 1.2" isn't a useful bug report because we _expect_
GTK+-2.0 to be generally slower than GTK+-1.2. Not being
magicians, more features, nicer rendering, etc, generally
means slower. So, "slower than 1.2" isn't a useful bug
unless you can point to:

 - Some obviously buggy performance characteristic (some
   operation is O(n^2) when it used to be O(n), say.)
 - A particular feature you feel should be dropped because
   of its performance impact.
 - A particular performance improvement that you suggest
   should be made.

Caches are dangerous critters - can easily do more harm
than good; if you don't limit the size of your cache than
you can use tons of memory. If you do limit the size 
of the cache, then with the number of active items, you
get a performance profile that looks like:

 -----------\
             |
             |
             |
             \----------------------
 -----------------------------------

It's better to attack the source of the problem than the
symptoms.

Also, we can't cache composited pixmaps on the server because
we don't know the background we are compositing against.

Some comments on the quantify reports:

 10.30%   gdk_keymap_get_entries_for_keyval

The fact that this is at the top implies to me that you
probably tested the _initial_ keypress  on the window,
which distorts the result a bit.

  2.13%   _XGetPixel32

The fact you have GetPixel and PutPixel in the list
suggests to me that convert_real_slow() in gdkpixbuf-drawable
is being used. If this is the case, then writing a special-cased
converter that handles your visual would help somewhat.

But I really think that the:

 - Remote display on Solaris

And the:

 - Local display on Linux 

Cases are not very comparable. The linux case is probably
slow because it's a slow machine, and improvements are going
to be of the profile-look-for-hotspots-optimize variety.
(200msecs seems like a long time. I don't know why it would
be that long.)

The solaris case is probably slow principally because 
get-image/composite/put-image drawing is inherently slow
on a remote link (though it seems perfectly fine to me
over 100mbps to me ... not sure how remote Morten's 
"remote link" was.)

If we want to optimize the really-remote link case, the 
only real real way to do that is to have a GtkSetting
to make GtkImage not do full alpha-composite, but rather
to render_pixbuf_and_mask(). 

There is also missing information in the Linux case about
what XFree86 version is used, what font rendering system
(Xft or core X) is being used.
Comment 9 Morten Welinder 2002-10-04 13:28:45 UTC
Solaris 2.8 big-iron box connected locally to my sparc desktop.
Connection is 100Mb/s.

Yes, this was on the first round.  Here are new info for the
second round.

 8.77%   g_type_check_instance_cast
 7.16%   g_type_check_instance_is_a
 3.62%   composite_0888
 3.29%   g_type_value_table_peek
 2.93%   mutex_unlock
 2.83%   _XGetPixel32
 2.62%   signal_emit_unlocked_R
 2.45%   gdk_pixbuf_saturate_and_pixelate
 2.44%   g_signal_emit_valist
 2.21%   strcmp
 2.09%   .umul
 2.03%   g_hash_table_lookup
 1.97%   _XPutPixel32
 1.93%   g_type_is_a
 1.71%   mutex_lock
 1.69%   Letext[libgobject-2.0.so.0.100.0/361]
 1.68%   g_type_check_is_value_type
 1.45%   g_type_check_value
 1.44%   _free_unlocked
 1.26%   bilinear_make_fast_weights
 1.19%   g_static_rw_lock_reader_unlock
 1.13%   _XSetImage
 1.08%   g_static_rw_lock_reader_lock
 0.90%   cleanfree
 0.88%   _malloc_unlocked
 0.84%   g_object_unref
 0.78%   g_datalist_id_set_data_full
 0.74%   memcpy
 0.71%   realfree
 0.69%   g_value_init
 0.68%   g_object_ref
 0.66%   gtk_object_get_type
 0.66%   scale_line
 0.64%   param_spec_pool_hash
 0.63%   gtk_widget_get_type
 0.61%   g_value_type_compatible
 0.58%   g_value_unset
 0.58%   g_type_check_instance
 0.57%   g_signal_lookup
 0.51%   g_value_set_instance
 0.50%   g_closure_invoke

16% of the time spend casting pointers?  Ick.



 100.00%   g_main_context_iterate
  99.30%   g_main_context_dispatch
  99.28%   g_main_dispatch
  81.11%   g_signal_emit_valist
  76.23%   gtk_signal_emit
  74.36%   signal_emit_unlocked_R
  72.91%   g_closure_invoke
  71.68%   g_type_class_meta_marshal
  70.02%   gtk_main_do_event
  68.19%   gtk_widget_event_internal
  65.69%   _gtk_marshal_BOOLEAN__BOXED
  48.43%   g_idle_dispatch
  44.33%   gdk_window_process_all_updates
  44.26%   gdk_window_process_updates_internal
  43.24%   gtk_container_idle_sizer
  42.73%   gtk_container_forall
  42.16%   wbcg_menu_state_sensitivity
  42.09%   gtk_widget_send_expose
  42.03%   bonobo_ui_component_set_prop
  42.03%   impl_set_prop
  42.03%   Bonobo_UIContainer_setAttr
  42.03%   impl_Bonobo_UIContainer_setAttr
  42.03%   bonobo_ui_engine_xml_set_prop
  41.96%   bonobo_ui_engine_update
  38.18%   gtk_bin_forall
  36.89%   gtk_container_expose
  36.86%   gtk_container_propagate_expose
  36.84%   gtk_container_expose_child
  35.34%   bonobo_ui_engine_update_node
  35.20%   do_sync
  34.24%   bonobo_ui_engine_sync
  31.65%   bonobo_ui_sync_state
  31.61%   impl_bonobo_ui_sync_toolbar_state
  31.15%   bonobo_dock_item_expose
  30.43%   bonobo_dock_item_forall
  30.27%   impl_expose_event[libbonoboui-2.so.0.0.0/1040]
  29.48%   gtk_box_forall
  29.33%   gdk_event_dispatch
  26.14%   gtk_widget_event
  24.43%   gtk_button_expose
  23.38%   gtk_propagate_event
  22.79%   bonobo_ui_toolbar_button_item_set_label
  22.75%   impl_set_label[libbonoboui-2.so.0.0.0/923]
  21.90%   bonobo_window_key_press_event
  21.90%   gtk_window_key_press_event
  21.86%   gnm_canvas_key_press
  21.46%   g_timeout_dispatch
  21.40%   cb_thaw_ui_toolbar
  21.34%   g_signal_emit_by_name
  21.33%   wb_control_edit_set_sensitive
  21.33%   wbcg_edit_set_sensitive
  21.22%   gtk_im_context_filter_keypress
  21.22%   gtk_im_multicontext_filter_keypress
  21.22%   gtk_im_context_simple_filter_keypress
  21.21%   no_sequence_matches
  21.20%   gtk_im_context_simple_commit_char
  21.20%   g_cclosure_marshal_VOID__STRING
  21.20%   gtk_im_multicontext_commit_cb
  21.19%   gnm_canvas_commit_cb
  21.10%   wbcg_edit_start
  20.22%   gtk_image_expose
  14.31%   gdk_draw_pixbuf
  14.10%   g_signal_emit
  13.98%   gdk_window_draw_pixbuf
  13.76%   gdk_pixmap_draw_pixbuf
  13.72%   gdk_drawable_real_draw_pixbuf
  11.74%   set_label
  11.22%   layout_pixmap_and_label
  10.90%   gtk_box_pack_end




440745   .umul
357274   Letext[libgobject-2.0.so.0.100.0/361]
103174   mutex_lock
103174   mutex_unlock
 87232   g_type_check_instance_cast
 79156   g_type_check_instance_is_a
 68636   g_type_value_table_peek
 52018   _XPutPixel32
 52018   _XGetPixel32
 50209   Letext[libgobject-2.0.so.0.100.0/462]
 47035   unknown_static_function[libgtk-x11-2.0.so.0.100.0/5443]
 38531   unknown_static_function[libgobject-2.0.so.0.100.0/68]
 36810   g_type_check_is_value_type
 34039   Letext[libglib-2.0.so.0.100.0/442]
 33637   unknown_static_function[libgtk-x11-2.0.so.0.100.0/2627]
 33613   strcmp
 31156   gtk_object_get_type
 29586   gtk_widget_get_type
 26879   Letext[libglib-2.0.so.0.100.0/748]
 25939   g_type_check_value
 24867   unknown_static_function[libglib-2.0.so.0.100.0/219]
 24289   .urem
 24002   g_type_is_a
 23483   g_hash_table_lookup
 19381   Letext[libglib-2.0.so.0.100.0/121]
 17590   g_free
 17498   param_spec_pool_equals
 16323   g_str_equal
 15978   unknown_static_function[libgobject-2.0.so.0.100.0/286]
 15969   signal_key_cmp
 15364   Letext[libgdk-x11-2.0.so.0.100.0/62]
 15147   _free_unlocked
 15146   free
 15103   _malloc_unlocked
 14989   malloc
 13432   realfree
 13109   cleanfree
 13072   Letext[libgobject-2.0.so.0.100.0/26]
 12587   g_value_init
 12587   g_value_unset
 12544   get_attr
 12290   g_object_unref
 12185   g_type_check_instance
 12138   boxed_nodes_cmp
 11988   _smalloc
 11971   unknown_static_function[libgdk-x11-2.0.so.0.100.0/789]
 11926   g_object_ref
 11696   g_value_type_compatible
 11642   g_static_rw_lock_reader_unlock
 11642   g_static_rw_lock_reader_lock
 11264   g_value_object_free_value
 10466   unknown_static_function[libgdk_pixbuf-2.0.so.0.100.0/1]
 10425   g_malloc
 10120   bonobo_ui_node_get_data
  9533   Letext[libgdk-x11-2.0.so.0.100.0/152]
  9119   unknown_static_function[libgobject-2.0.so.0.100.0/6]
  9112   param_spec_pool_hash
  8683   g_type_parent
  8654   _gdk_gc_x11_get_type
  8268   g_direct_hash
  7942   Letext[libgdk-x11-2.0.so.0.100.0/440]
  7866   unknown_static_function[libgdk-x11-2.0.so.0.100.0/392]
  7840   gdk_drawable_get_type
  7664   unknown_static_function[libgtk-x11-2.0.so.0.100.0/766]
  7537   .udiv
  7445   g_datalist_id_get_data
  6831   g_value_peek_pointer
  6831   g_value_object_peek_pointer
  6601   gdk_gc_get_type
  6384   g_str_hash
  6349   memset
  6221   Letext[libgobject-2.0.so.0.100.0/135]
  6048   gdk_pixbuf_get_n_channels
  5794   handler_lists_cmp
  5760   g_closure_unref
  5632   g_value_object_collect_value
  5632   g_value_object_init
  5576   unknown_static_function[libgobject-2.0.so.0.100.0/583]
  5538   gdk_window_object_get_type
  5524   gtk_container_get_type
  5416   g_type_check_value_holds
  5273   Letext[libgdk-x11-2.0.so.0.100.0/707]
  5270   calloc
  5212   Letext[libbonoboui-2.so.0.0.0/1092]
  5212   Letext[libgdk-x11-2.0.so.0.100.0/948]
  5174   g_malloc0
  5118   g_signal_emit_valist
  5118   signal_emit_unlocked_R
  5118   g_value_set_instance
  5060   bonobo_ui_xml_get_data
  4984   g_closure_invoke
  4929   _gdk_drawable_impl_x11_get_type
  4529   _gdk_screen_x11_get_type
  4521   g_datalist_id_set_data_full
  4469   g_type_class_meta_marshal
  4368   g_type_check_class_cast
  4350   Letext[libgobject-2.0.so.0.100.0/581]
  4034   boxed_proxy_value_free
  4024   Letext[libbonoboui-2.so.0.0.0/802]
  3960   unknown_static_function[libgtk-x11-2.0.so.0.100.0/5631]
  3909   unknown_static_function[libgtk-x11-2.0.so.0.100.0/3257]
  3848   g_quark_from_string
  3642   memcpy
  3599   gtk_window_get_type
  3407   gtk_signal_emit
  3332   bonobo_ui_node_get_attr_by_id
  3310   .div
  3233   unknown_static_function[libgtk-x11-2.0.so.0.100.0/1895]
  3136   bonobo_ui_sync_get_type
  3114   Letext[libbonoboui-2.so.0.0.0/954]
  2874   strlen
  2769   g_list_alloc
  2738   Letext[libglib-2.0.so.0.100.0/334]
  2727   g_strdup
  2720   style_property_values_cmp
  2506   bonobo_ui_node_next
  2377   unknown_static_function[libgtk-x11-2.0.so.0.100.0/3377]
  2376   value_param_free_value
  2282   floor
  2217   gdk_region_destroy
  2212   Letext[libgdk-x11-2.0.so.0.100.0/266]
  2181   g_list_free_1
  2095   g_value_set_boolean
  2082   Letext[libgdk-x11-2.0.so.0.100.0/605]
  2048   bonobo_ui_node_children
  2017   boxed_proxy_value_init
  2017   boxed_proxy_collect_value
  2016   unknown_static_function[libgdk-x11-2.0.so.0.100.0/1010]
  1954   Letext[libgtk-x11-2.0.so.0.100.0/1588]
  1942   gtk_widget_ref
  1942   gtk_widget_unref
  1870   bonobo_ui_toolbar_item_get_type
  1868   g_quark_try_string
  1860   gtk_widget_get_toplevel
  1824   g_param_spec_pool_lookup
  1812   _gdk_display_x11_get_type
  1804   g_slist_free
  1736   g_static_rw_lock_writer_lock
  1736   g_static_rw_lock_writer_unlock
  1698   Letext[libgtk-x11-2.0.so.0.100.0/3269]
  1685   g_signal_emit
  1679   strcpy
  1676   gdk_region_rectangle
  1673   g_object_get_qdata
  1635   gdk_window_impl_x11_get_type
  1614   g_value_get_boolean
  1566   g_slist_alloc
  1554   Letext[libgdk_pixbuf-2.0.so.0.100.0/127]
  1536   correct_total
  1533   g_slist_prepend
  1532   gtk_label_get_type
  1468   value_lcopy_boolean
  1440   get_size_groups
  1430   Letext[libbonoboui-2.so.0.0.0/592]
  1389   gdk_x11_gc_values_to_xvalues
  1382   g_value_reset
  1371   gdk_pixmap_get_type
  1369   Letext[libgdk-x11-2.0.so.0.100.0/42]
  1361   thr_main
  1361   ___errno
  1354   t_delete
  1328   gtk_object_get_data_by_id
  1324   _gtk_boolean_handled_accumulator
  1324   Letext[libgtk-x11-2.0.so.0.100.0/123]
  1320   seek_dirty
  1281   gdk_x11_gc_set_values
  1281   gdk_gc_set_values
  1281   XChangeGC
  1228   strchr
  1217   gdk_display_get_type
  1203   t_splay
  1199   gtk_style_get_type
  1188   value_param_collect_value
  1188   g_param_spec_unref
  1188   g_param_spec_ref
  1188   value_param_init
  1158   bonobo_ui_node_get_attr
  1152   g_type_fundamental
  1148   gdk_region_intersect
  1148   miSetExtents
  1101   gdk_region_empty
  1098   Letext[libpango-1.0.so.0.0.1/224]
  1089   gdk_pixbuf_get_has_alpha
  1087   g_object_notify_queue_free[libgobject-2.0.so.0.100.0/67]
  1065   gdk_pixbuf_get_pixels
  1062   gdk_pixbuf_get_rowstride
  1061   g_signal_handlers_destroy
  1038   gdk_drawable_get_screen
  1021   art_affine_point

That's an obscene number of function calls.
Comment 10 Morten Welinder 2002-10-04 13:43:27 UTC
How hard would it be for toolbars to notice small icons (==all)
and keep the result of gdk_pixbuf_render_to_drawable around?
(Or whatever, as-if I know what I am talking about.)

Owen: the reason that get-image/composite/put-image seems adequate
to you might be that you don't have enough icons.  Gnumeric just
simply has a lot.

_X{Put,Get}Pixel32 are only called from _XSetImage which is only
called from XGetSubImage which is only called from
_gdk_x11_copy_to_image which is only called from
_gdk_drawable_real_draw_pixbuf from gdk_draw_pixbuf.  (At that point
it gets complicated.)  No function "*real_slow*" is called.

We also spend 11.75% in set_label in bonobo-ui-toolbar-button-item.c
MICHAEL: that's absurd.  Could you have a look at the FIXME in that
function, please?
Comment 11 Owen Taylor 2002-10-04 15:08:04 UTC
The first thing that needs to be investigated is how much
of the slowness is actually in the gnumeric process and how
much is network overhead and Xserver overhead - if GTK+
only accounts for 10% of the total time, then even if
you made GTK+ 10 times faster, you'd speed things up
by 9%.

It woudl be useful to know _which_ type checks are taking
all the time. Selectively removing a few type checks 
or providing unchecked variants for internal use can
help a lot.

At best by caching you can save the call to saturate-and-pixelate;
you can't save the compositing calls because you don't know
what you are compositing on top of .

_XSetImage() indeed does a loop over pixels and 
contains the comment:

        /* this is slow, will do better later */
        for (row = startrow; row < height; row++) {
            for (col = startcol; col < width; col++) {
                pixel = XGetPixel(srcimg, col, row);
                XPutPixel(dstimg, x + col, y + row, pixel);
            }
        }

I suspect that comment was written in 1988 or so...
Comment 12 Morten Welinder 2002-10-04 15:44:53 UTC
Re. "which type check":

Data from gnumeric (pid 5800)
Note: Recursive descendants are marked with an '*'.

Function name:                 g_type_check_instance_cast
Filename:                     
/home/welinder/private/gnome/glib/gobject/gtype.c
Called:                          87232 times
Function time:                 3704330 cycles ( 8.77% of .root.)
Function+descendants time:     3883010 cycles ( 9.20% of .root.)
Average function time:              42 cycles
Minimum function time:              42 cycles
Maximum function time:              92 cycles

Distribution to callers:
10323 times (11.70%)  gtk_widget_propagate_state
 5124 times ( 5.81%)  gdk_x11_gc_set_values
 3407 times ( 4.12%)  gtk_signal_emit
 3386 times ( 3.84%)  _gdk_x11_gc_flush
 3175 times ( 3.60%)  gtk_widget_event_internal
 2526 times ( 2.86%)  gtk_container_propagate_expose
 1800 times ( 2.04%)  size_allocate_helper
 1680 times ( 2.03%)  gtk_widget_child_notify
 1440 times ( 1.74%)  get_size_groups
 1328 times ( 1.61%)  gtk_object_get_data_by_id
 1340 times ( 1.56%)  gtk_widget_unparent
 1344 times ( 1.53%)  gtk_widget_set_parent
 1311 times ( 1.49%)  gdk_x11_draw_segments
 1211 times ( 1.37%)  gdk_event_translate
 1116 times ( 1.26%)  gtk_container_expose
 1058 times ( 1.20%)  _gtk_button_paint
  930 times ( 1.05%)  gdk_pixmap_new
  901 times ( 1.02%)  gtk_widget_is_focus
  881 times ( 1.00%)  gdk_window_is_viewable


Data from gnumeric (pid 5800)
Note: Recursive descendants are marked with an '*'.

Function name:                 g_type_check_instance_is_a
Filename:                     
/home/welinder/private/gnome/glib/gobject/gtype.c
Called:                          79156 times
Function time:                 3023004 cycles ( 7.16% of .root.)
Function+descendants time:     3186028 cycles ( 7.55% of .root.)
Average function time:              38 cycles
Minimum function time:              38 cycles
Maximum function time:              88 cycles

Distribution to callers:
12290 times (15.43%)  g_object_unref
11926 times (14.97%)  g_object_ref
 3407 times ( 4.28%)  gtk_signal_emit
 1942 times ( 2.44%)  gtk_widget_ref
 1942 times ( 2.44%)  gtk_widget_unref
 1860 times ( 2.34%)  gtk_widget_get_toplevel
 1798 times ( 2.26%)  gtk_widget_is_focus
 1673 times ( 2.10%)  g_object_get_qdata
 1560 times ( 1.96%)  gdk_draw_segments
 1364 times ( 1.71%)  gtk_container_propagate_expose
 1328 times ( 1.67%)  gtk_object_get_data_by_id
 1281 times ( 1.61%)  gdk_gc_set_values
 1281 times ( 1.61%)  gdk_x11_gc_set_values
 1188 times ( 1.49%)  g_param_spec_unref
 1188 times ( 1.49%)  g_param_spec_ref
 1038 times ( 1.30%)  gdk_drawable_get_screen
  908 times ( 1.14%)  gdk_drawable_get_visible_region
  874 times ( 1.10%)  gdk_draw_line
  858 times ( 1.08%)  gtk_container_forall
  772 times ( 1.07%)  gtk_widget_propagate_state
  809 times ( 1.02%)  gtk_widget_get_name
  800 times ( 1.00%)  gdk_drawable_get_colormap


Also, I must be missing something obvious.  There are two "looks"
for the buttons: active and disabled.  From 1 mile distance, the
disabled/re-enabling is a matter of painting 40 bitmaps -- the
same two sets of 40 bitmaps every time.  Let's allow 50ms for that
on the remote link.  Now, the code is probably very general, but
surely something in there must know that our icons are not animated,
rotating, scaled, and semi-transparent.  And that they are sitting
on a solid grey background.

So I am wondering how we can recognise the painfully simple common
situation and just blast the bits out there, preferably totally
invisible to the programmer.

Comment 13 Michael Meeks 2002-10-08 11:04:39 UTC
Hi Morten:

> We also spend 11.75% in set_label in bonobo-ui-toolbar-button-item.c
> MICHAEL: that's absurd.  Could you have a look at the FIXME in that
> function, please?

   Fixed in CVS, 2 fixes - but it'd be nice to have them in Gtk+
really instead of hacking around them elsewhere. Essentially - doing a
string compare on the label before re-setting it to the same thing [
and spewing a huge chain of widget sizing / etc. logic ].

   I imagine a substantial part of the problem is the round-trip image
compositing on your [ non X-render I assume ] display. Every icon that
is composited [ even if on a flat grey theme ] has to do a server
round-trip per icon rendered - which is horribly slow. It's not clear
really what to do about that though.
Comment 14 Mike Uber Otriz 2003-06-03 20:32:17 UTC
Created attachment 17104 [details]
test case isolating the gtk+ toolbar code
Comment 15 Mike Uber Otriz 2003-06-03 20:33:12 UTC
Created attachment 17105 [details]
Makefile for the lazy
Comment 16 Chema Celorio 2003-06-09 19:57:18 UTC
Created attachment 17370 [details]
updated version of the test file
Comment 17 Chema Celorio 2003-06-09 19:58:29 UTC
Downloaded and played with the test file, I modified it a bit added an
entry and every time a key is pressed the toolbar sensitivity is
toggled so as to mimic the gnumeric behaviour better.

Thanks for the test code Mike
Comment 18 Michael Meeks 2003-06-10 08:23:42 UTC
Of course - the two main calls to saturate_and_pixelate pass in two
fixed floating point values; those hard-coded fixed values can ~easily
be pushed down into the method itself and result in quite a pleasant
simplification of that method - pwrt. removing several double
precision multiplies per pixel - quite a win on a Sparc I guess.
Comment 19 Morten Welinder 2003-06-13 14:49:40 UTC
That would be about 52 icons at 256 pixels/icon at about 5 mults/pixel,
i.e., about 66k extra mults for greying.

Further saving could be had by realising that

#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)

could be replaced by three table lookups.
Comment 20 Jason Mancini 2003-11-21 22:18:40 UTC
Random thought:

#define INTENSITY(r, g, b) \
  ((19660*(r) + 38666*(g) + 7208*(b) + 32768)>>16)
Comment 21 Jon Kåre Hellan 2004-08-19 17:56:18 UTC
Much better in HEAD. Over ADSL (512/64 kB), delay is noticable, but not really a 
problem. 
Comment 22 Federico Mena Quintero 2004-09-17 21:32:52 UTC
This really needs something like the fix I put in for bonobo-1.4.  It has a
two-level cache of pixmaps.  As Owen says, it probably didn't do the right thing
with respect to compositing, but perhaps one could hack gtktoolbutton to render
its whole area to a pixmap and cache that.
Comment 23 Federico Mena Quintero 2005-06-14 20:02:43 UTC
Anyone who cares about this should really look into the cache I put into
bonobo-1.4.  It's very simple.
Comment 24 Andreas J. Guelzow 2009-09-06 09:29:17 UTC
Is this still an issue?
Comment 25 Morten Welinder 2009-09-09 02:07:02 UTC
> Is this still an issue?

A quick test (using valgrind to slow things down...) suggests that in the
local-display-on-Linux case this is not an issue at present.

The non-local-on-Linux display (using ssh -X and valgrind) suggests that
this case is ok too.

A million things could have caused this: not using bonobo's menu code;
newer X servers; gtk+ changes; etc.