2007-12-25

25 12 2007

So I kept profiling m-m today.

I found that g_get_language_names called g_getenv a lot, which in turn calls getenv. This account for ~5% of the startup time of m-m as seen below;

m-m-org-glib

Since I know that Michael Meeks came to this same conclusion in his blog about gnome-menus, I decided to run a quick test with gnome-menu-spec-test. The result is this;

g-m-org-glib

Having a look at g_get_language_names I found that it does have a cache for language names, but it didn’t seem to be used efficiently. Now, I don’t know if there is a reason to find out if the language has changed while a program is running, but for the life of me, I can’t think of one.

Here’s a small snippet of the code;


if (!cache)
{
cache = g_new0 (GLanguageNamesCache, 1);
g_static_private_set (&cache_private, cache, language_names_cache_free);
}
value = guess_category_value ("LC_MESSAGES");
if (!value)
value = "C";
if (!(cache->languages && strcmp (cache->languages, value) == 0))
{
gchar **languages;
gchar **alist, **a;

It checks to see if it cached the language and if it did, retrieve the cache. Then it goes to check the language variables (no matter if it had a cache or not). I made a simple code change to NOT check the variables if the cache exists. Since I’ve never looked at the glib2 code before, I don’t know if the patch is sane, so I’ve asked for a review. But the cache here is per application, so changing the environment variables and starting a new application will work.

Result of the code change is this for m-m;

m-m-new-glib

And this for gnome-menus;

g-m-new-glib

Advertisements




2007-12-23

23 12 2007

The openSUSE GNOME Team spent last week hunting bugs in the GNOME Main Menu. Since I was on site at a customer, I entirely missed the event :-/

So I thought I should try to make up for it, by profiling g-m-m today.

The first thing I found was this;

document_tile_private_setup

Adding Favorite Documents and Recently Used Documents to m-m accounts for >20% of it’s startup time. Out of that, 19% is spent in gnome_vfs_mime_get_default_application.

Looking at the code for it reveals (surprise surprise) that it’s used to figure out what default application to open the document with. It seemed unnecessary to call such an expensive function for each Document so I decided to move it out of there. That meant that for each application, document_tile_private_setup would now use a standard function (run a function which in turn opens nautilus) instead. That standard function will only be called if the user clicks on a Document, so I added the call to gnome_vfs_mime_get_default_application in there. This will not only save valuable startup time, but also a little bit of memory.

The next thing I looked at, and it is one of my favorite things to do in Slab, is the creation of a context menu for each Document. Again, the only time it would be used, is if the user right clicks on a Document. So I modified the code to only create the context menu if the user right-clicks on a document. Again, some savings in both startup time and memory.

Then the third thing, and which took most of the time today, was the fix up the following;

g-m-m-init

The create_rct_docs_section accounts for 45% of the initialization here. All up, tile_table_new, which is called by each function that adds an item to m-m, is using 57%.

After moving the code around a bit (sounds easy doesn’t it?), and also fixed a bug, I ended up with this;

g-m-m-opt1

Now, that looks alright for a days work. Although not all finished with this yet (need to fix a bug that I introduced :-), it was a good day overall.

I tried to publish the diff here but wordpress didn’t like it much. Download it from here instead.

UPDATE!
I just realized that it looks a bit funny when comparing the two charts above. To clarify, it does not mean that the startup time have been reduced by >50%. These are numbers from the current view that I was looking at. Some of the work is now done in other functions which is not visible in the last chart. Once done with this first round of optimizations, I’ll try to publish a better view which shows how much we’ve gained.





2007-12-16

16 12 2007

I’ve been putting experimental code in AB to use a sqlite database for application cache.

To start, I created three tables;

create table Category (name TEXT PRIMARY KEY, id INTEGER);
create table Desktop (name TEXT, genericname TEXT, comment TEXT, exec TEXT, path TEXT PRIMARY KEY, id INTEGER);
create table DesktopCategory (desktop INTEGER, category INTEGER);

I then populate Category with the different categories, Desktop with all the applications and then the relationship table between Desktop applications and Categories.

On a warm startup (ie. everything is in filesystem cache), it saves 20% of the startup time compared to using gnome-menus.

I need to play around with this a bit more, but if it proves to be a feasible solution, then it’d be a good idea to store even more data in the database.

The biggest problem with doing it this way instead of using realtime data is obviously if AB doesn’t get started for a while and new software is added or removed. We’d end up for bad data.

Here’s AB using gnome-menus

AB using gnome-menus

And here’s AB using sqlite

AB using sqlite





2007-12-13

13 12 2007

I’ve been playing with Application Browser from the tile-2 repo. It’s nothing like AB in the original code and it feels so much faster.

Unfortunately, the previous profiling were done on my old machine which is no longer with us. Although not very important, it’d still be interesting to see how the two versions compare, so I will get some numbers from both and put them up here.

I’ve been running the new AB through valgrind to get a handle on what this new code is doing. While checking the results in kcachegrind, I found this tab called “Call Graph”, so I clicked on it. And for a while, I thought I died and went to heaven 🙂

This fantastic graph popped up my screen

callgrind-output-tile-2

I have yet to figure out if it can give me time instead of percentage, but it will certainly make life easier either way!

Apparently, Mikael Meeks have some ideas on what to do with gnome-menus  (in which AB spends ~30% of it’s time), so looking forward to hear his ideas.





2007-12-12

12 12 2007

Time has come to drop the previous profiling and start looking at tile-2 from GNOME svn instead.

I checked out the code this morning and had a look at it. Also took it for a test run and it feels a bit faster.

Next, I’ll have to add the “poor mans profiling” code again. I’ll also make use of callgrind.

As soon as I have the first profiling done, I’ll submit a patch so that the context menu is not added on startup, but when the user right-clicks on an application.

Hope to get some time tomorrow to put up some nice graphs from the first round of profiling.





2007-12-02

12 12 2007

Sunday morning, 7.30am. Should really be in bed still but have had problems with sleeping in lately. That’s good and bad I guess. The good is that I have more time, The bad is.. uhm… Well, I’m sure there’s something bad with not sleeping enough.

Good to see that Michael Meeks is on the case of optimizing as well.

With regards to performance, I don’t think it’s ever possible to optimize to the point where AB pops up within a second without changing the way it works. At the moment, it will make a call to gtk_widget_show_all which is the most expensive operation in the code. Even if some optimization can be done, the time it takes to show AB will always depend on how many .desktop files you have.

The way to get around that would be to show the window with only the number of apps that are visible, then once it’s shown, add the rest of the apps.

I’ve been experimenting with it, using a loop like this;

void ui_itterator(GtkWidget *wid, gpointer unused)

{

      if (GTK_IS_CONTAINER(wid)) {

            gtk_widget_show(wid);

            while (gtk_events_pending())

                  gtk_main_iteration();

            gtk_container_foreach(GTK_CONTAINER(wid), ui_itterator, NULL);

}      gtk_widget_show(wid);

      while (gtk_events_pending())

            gtk_main_iteration();

}

No need to start laughing! It’s only an experiment to see how it works 🙂 I need to spend more time with it and figure out how to show all widgets but the apps, calculate how many apps that will fit in the visible window space, then loop through to show them.

I don’t know if this is the best approach but something like this is needed for sure. Looking at Nautilus, it will show the window with nothing in it until it fetched all files so I hope I’m on the right track here.





2007-11-30

12 12 2007

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.