Saturday, November 17, 2007

2007-11-17

G'day!

To start off, just a disclaimer...
I've not done any GNOME/GTK development ever nor am I very experienced in GUI programming. What I'm hoping to get out of this is; 1) Experience with GNOME/GTK, 2) Experience with debugging and 3) A super fast menu system :-)

And off course, chances are that posts that has nothing to do with Slab finds is way here as well.

So this is my first post about Slab, the new GNOME Main Menu. I'm currently looking at ways to make it perform as it was on drugs.

I will start off by profiling the Application Browser (AB).

In order to improve performance, one should start by profiling the application. At least that's what Federico says, so that is what I will do :-)
After profiling is complete, one needs to decide what to optimize. Again, Federico says that you can't optimize without having goals, and again, I will obey.

I've actually already cheated and done some profiling that I posted on the openSUSE wiki. But for the purpose of this blog, I will start all over :-)

So the first thing to do is to add some debug code. I'm going to use the following (very simple, but yet not very elegant function :-)


void timeCount(char *funcName)
{
struct timeval tv;
gettimeofday(&tv, NULL);
long tms;
int i = 0;
int func = -1;
char *formatted, *str;

tms = tv.tv_sec * 1000 + tv.tv_usec / 1000;

while(lapse[i].last) {
if(!strcmp(funcName, lapse[i].funcName)) {
func = i;
break;
}
i++;
}

if(func == -1)
func = i;

if(!lapse[func].last) {
strcpy(lapse[func].funcName, funcName);
lapse[func].hello = 0;
}

if(!lapse[func].init) {
lapse[func].last = tms;
lapse[func].init = 1;
lapse[func].hello += 1;
str = g_strdup_printf ("MARK: %s: %s Begin", g_get_prgname(), funcName);
}
else {
lapse[func].curtime = (tms-lapse[func].last)+lapse[func].curtime;
lapse[func].init = 0;
str = g_strdup_printf ("MARK: %s: %s End", g_get_prgname(), funcName);
}

access (str, F_OK);
g_free (str);
}


Now I need to add this function to the beginning and end of various functions that I want to profile. I also add an exit statement in the application instead of calling gtk_main(). This allows me to run in batch mode without having to kill AB.

Then I start the application as follows;
strace -ttt -f -o test-strace.log application-browser

Once done, I use plot-timeline.py to generate a pretty picture.

The end result becomes this;



And this (Second column is the number of times the function was called and the third column is the total time spent in that function);

"generate_categories","1","1919"
"generate_categories ==> gmenu_tree_get_root_directory (app_data->tree)","1","854"
"generate_new_apps","1","44"
"layout_shell","1","12"
"create_main_window","1","1374"
"show_shell","1","1361"
"gtk_widget_show_all","1","1361"

After sprinkling some more debug code (and also added the option to not include a specific function in the plot), the result is;



"main","1","0"
"generate_categories","1","2588"
"generate_categories ==> gmenu_tree_get_root_directory (app_data->tree)","1","860"
"generate_category","9","1666"
"generate_launchers","95","762"
"check_specific_apps_hack","154","19"
"insert_launcher_into_category","162","1545"
"application_tile_new_full","162","1130"
"nameplate_tile_class_init","1","0"
"nameplate_tile_constructor","172","117"
"nameplate_tile_init","172","11"
"nameplate_tile_setup","172","41"
"application_tile_setup","162","851"
"themed_icon_new","162","52"
"themed_icon_set_property","324","18"
"nameplate_tile_set_property","678","198"
"themed_icon_show","162","127"
"libslab_get_gconf_value","1","7"
"libslab_gconf_notify_add","1","0"
"libslab_gnome_desktop_item_new_from_unknown_id","13","12"
"application_launcher_compare","3212","193"
"generate_new_apps","1","62"
"layout_shell","1","27"
"app_resizer_new","1","0"
"app_resizer_get_type","24","0"
"app_resizer_class_init","1","0"
"create_application_category_sections","1","13"
"populate_application_category_sections","1","9"
"remove_container_entries","12","1"
"populate_application_category_section","10","8"
"app_resizer_layout_table_default","10","5"
"resize_table","10","2"
"relayout_table","10","3"
"app_resizer_set_table_cache","1","0"
"create_filter_section","1","1"
"create_groups_section","1","0"
"populate_groups_section","1","0"
"create_actions_section","1","0"
"create_main_window","1","1377"
"show_shell","1","1364"
"gtk_widget_show_all","1","1364"
"themed_icon_style_set","162","202"
"app_resizer_size_allocate","3","65"
"relayout_tables_if_needed","2","0"
"calculate_num_cols","2","0"

Running the same as above, but without strace will render completely different numbers. So for the sake of being able to create pretty pictures throughout this exercise, strace will only be used when we need to create a new pretty picture and we can then compare that to what we have above. The numbers below were generated without using strace.

"generate_categories","1","821"
"generate_categories ==> gmenu_tree_get_root_directory (app_data->tree)","1","337"
"generate_category","9","463"
"generate_launchers","95","216"
"check_specific_apps_hack","154","0"
"insert_launcher_into_category","162","453"
"application_tile_new_full","162","400"
"nameplate_tile_class_init","1","0"
"nameplate_tile_constructor","172","53"
"nameplate_tile_init","172","0"
"nameplate_tile_setup","172","29"
"application_tile_setup","162","314"
"themed_icon_new","162","6"
"themed_icon_set_property","324","0"
"nameplate_tile_set_property","678","76"
"themed_icon_show","162","54"
"libslab_get_gconf_value","1","0"
"libslab_gconf_notify_add","1","1"
"libslab_gnome_desktop_item_new_from_unknown_id","13","2"
"application_launcher_compare","3212","2"
"generate_new_apps","1","21"
"layout_shell","1","11"
"app_resizer_new","1","0"
"app_resizer_get_type","24","0"
"app_resizer_class_init","1","0"
"create_application_category_sections","1","6"
"populate_application_category_sections","1","2"
"remove_container_entries","12","0"
"populate_application_category_section","10","1"
"app_resizer_layout_table_default","10","1"
"resize_table","10","0"
"relayout_table","10","1"
"app_resizer_set_table_cache","1","0"
"create_filter_section","1","0"
"create_groups_section","1","1"
"populate_groups_section","1","0"
"create_actions_section","1","0"
"create_main_window","1","1156"
"show_shell","1","1144"
"gtk_widget_show_all","1","1144"
"themed_icon_style_set","162","178"
"app_resizer_size_allocate","3","58"
"relayout_tables_if_needed","2","0"
"calculate_num_cols","2","0"

1 comment:

Michael Wolf said...

Can you configure your feed to not truncate entries?

ta