GNOME Bugzilla – Bug 94718
Graying of menu/toolbars eats lots of cpu
Last modified: 2009-09-09 02:07:02 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 ?
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.
"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.
Re-opening to gather more info.
Mine, mine, mine.
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.
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...)
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.
"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.
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.
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?
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...
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.
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.
Created attachment 17104 [details] test case isolating the gtk+ toolbar code
Created attachment 17105 [details] Makefile for the lazy
Created attachment 17370 [details] updated version of the test file
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
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.
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.
Random thought: #define INTENSITY(r, g, b) \ ((19660*(r) + 38666*(g) + 7208*(b) + 32768)>>16)
Much better in HEAD. Over ADSL (512/64 kB), delay is noticable, but not really a problem.
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.
Anyone who cares about this should really look into the cache I put into bonobo-1.4. It's very simple.
Is this still an issue?
> 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.