Friday, November 30, 2007

2007-11-30

Another Friday, another waking up at 3.45 in the morning. But it's worth it. Lot's of interesting things happen at that time in the morning, such as birds waking up, the absence of trains but specifically the openSUSE GNOME meeting on IRC (#opensuse-gnome on FreeNode).
It's a lot of fun participating in these meetings. Perhaps the most important, and fun, bit is the ability to influence the next version of openSUSE.

The openness of the GNOME team has been absolutely fantastic, and the influence that they let us "normal" people have is great, so a big thank you to them for making this happen!

Also, this morning, I got word that a patch I wrote for Slab was accepted;

Nov 30 03:05:15 captain_magnus: thanks for the flicker patch - I submitted it

Fun fun fun :-)

Having patches accepted not only gives you a feeling of having done something for the greater good (even though this particular patch was sort of a one liner) but also motivation to keep digging in to it.

Wednesday, November 28, 2007

2007-11-28

Had a look at a bug report for the Main Menu, where renaming a document doesn't properly update the URI for the file in the Recent Documents section. When I started playing with it, I found a bug in the rename routine for Recent Documents.
If you right-click on an item in Recent Documents, you can select Rename. It then makes the document name editable. But unless you press Enter, this field will stay editable. So you can go and right-click on all your documents, select rename and the result is something like this;



When talking to jpr on IRC, he suggested that it should instead behave like Nautilus. That behavior will save whatever is in the editing field, unless you press ESC which will undo the editing, and exit the editing mode.

So even though this haven't been reported as a bug, I'll have a look at it and see if I can fix it up.

Plenty of stuff to do, but so little time :-)

Tuesday, November 27, 2007

2007-11-26

Rodrigo told me about some ideas coming up for the control center (which is using libslab);

* http://liquidat.files.wordpress.com/2007/10/systemsettings.png
* http://bugzilla.gnome.org/attachment.cgi?id=82393&action=view
* No big sidebar on the control center?
* Few choices visible at one time
* Use the same padding as Nautilus

The first three should be very doable and not require all that much work (although not sure what the "arrow back" means)

The "Few Choices" and "Use same padding as Nautilus" probably goes hand in hand. The issue at the moment is that Slab is designed to work with one icon size, so the padding (ie. space between the items) are hard coded.

I've already raised this issue with the developers as I want to be able to have a configurable icon size.

More talk is needed with all parties to see what they want to do, but it feels like something fun to do in between measuring performance!

Wednesday, November 21, 2007

2007-11-21

Bought a new machine so that I could move to the fast lane. Intel Core2Quad 8Gb of memory situated on a ASUS Maximus mobo, running openSUSE 10.3 x86_64.
Makes all the difference when profiling and compiling stuff.
Need to figure out how to setup my developer environment though, so have not had time to do much performance work on AB yet.
As soon as I sort it out, graphs will follow :-)

Tuesday, November 20, 2007

2007-11-20

In a previous post, I mentioned that we need to have goals. I'm going to use Federicos goal of having the App Browser appear <1 second :-) Mission impossible? We will see...

We have numbers now, so it's time to take a closer look at the code. I mentioned that I've cheated and actually done some of this before. Well, I came as far as removing the creation of the context menu for each application. The menu that is added looks like this;



It'd be better to create it if/when a user actually right clicks on the application.

So after removing the code that creates the menu, we end up with the following stats;



Since this optimization business is not as simple as removing code that speed things up, we now need to come up with code to add this menu "on demand".

Sunday, November 18, 2007

2007-11-18

Just a quick post on how I use Git for my experiments.

I don't know if the way I use it is proper. The plan, at the end of the day, is to be able to merge optimized branches back to master, but without the code added in the profiling branch...

Get the latest sources via svn
mboman@mblxtv01:~/dev/gnome-main-menu> svn checkout svn://svn.gnome.org/svn/gnome-main-menu/branches/openSUSE-10.3/ branch-10.3

Create GIT repo
mboman@mblxtv01:~/dev/gnome-main-menu> cd branch-10.3
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git init
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git add .

Create a new branch
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git branch profiling master

Switch to profiling branch
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git checkout profiling

Add debug code, then commit
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git commit -a -m "Added/Modified Debug Code"


To actually test the debug code, I created a new clone;

mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> cd ..
mboman@mblxtv01:~/dev/gnome-main-menu> git clone branch-10.3 test
mboman@mblxtv01:~/dev/gnome-main-menu> cd test
mboman@mblxtv01:~/dev/gnome-main-menu/test> ./autogen.sh --libexecdir=/usr/lib/gnome-main-menu
mboman@mblxtv01:~/dev/gnome-main-menu/test> make
mboman@mblxtv01:~/dev/gnome-main-menu/test> sudo make install

After each time I did something in the profile branch and commited it;
mboman@mblxtv01:~/dev/gnome-main-menu/test> git pull
mboman@mblxtv01:~/dev/gnome-main-menu/test> make; sudo make install


Once the debug code is added and works as expected, create a new branch to try to optimize something specific.

Create a new branch for optimization test 1 (only create context menu when user right clicks on an application)
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git branch opt-context-menu profiling
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git checkout opt-context-menu

Tip: To see which branch you are actually working on;
mboman@mblxtv01:~/dev/gnome-main-menu/branch-10.3> git branch
master
* opt-context-menu
profiling

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"