24 Nov 2005

python mysteries

Today I was tracking down a GtkUIManager warning we get in gedit new_mdi when you have two windows open and you close one

 GtkWarning: gtk_container_foreach: assertion `GTK_IS_CONTAINER (container)' failed 

so I take a look at uimanager’s code and see that it does the unmerging in an idle handler, and the idle handler was being run even after the window was gone. Since GtkUImanager properly cancels the idle when finalized, I said, ok, we forgot to unref the ui_manager in window_finalize!
And in fact we did… I add the unref and guess what: warning is still there. Stick a printf in finalize and discover that window_finalize never runs! Its refcount is bumped to the magical number 7. After a bit of fiddling I discover that the culprit are python plugins and in particular

 py_ret = PyObject_CallMethod (object->instance, method, "(N)", pygobject_new (G_OBJECT (window))); 

The refcount of GeditWindow in during gedit_window_destroy it’s always 7 no matter how many python plugins I load and at the moment, given how python ignorant I am, I have no clue how I am supposed to solve that… Dear Lazyweb, any suggestions?

09 Nov 2005

#gnome-it

About a week ago I and ebassi decided to open a #gnome-it channel on irc.gnome.org (gimpnet): for the first days I just invited one by one the italian people I noticed hanging around in #gnome and #gtk+, but now that there is someone in the channel during most of the day, I think it’s time to give it more visibility, so…

gnomers italiani (hackers, traduttori, utenti), siete tutti invitati ad unirvi a #gnome-it su irc.gnome.org!

This is because there seems to be an increasing number of italian people involved in gnome, however we lack the flourishing community of gnome-es, gnome-fr and others… the old #gnome-it on freenode looked dead when I tried to join and it.gnome.org is outdated. An irc channel may not be a huge improvement but its a step in the right direction, so feel free to join and say ‘ciao’.

01 Nov 2005

Performance Work

Inspired by the recent performance love day and by the awesome work of Luis Menina and Federico about the slowness of ‘replace all’ in gedit, yesterday evening I decided to give it a look myself.

Federico explained in detail the first big offender (setting the sensitivity of the ‘find again’ menu item on every match), however once fixed that issue, ‘replace all’ is still fairly slow, so we need to continue our quest.
Next thing showing up in the profile is the statusbar code: the cursor position on the statusbar is updated every time the cursor moves, but that means that during ‘replace all’ the statusbar text changes on every match without need!

That said, I didn’t feel like hacking on the old gedit codebase: note that these issues do not affect the new_mdi branch in the same way, since we changed our internal search api. The code there is not yet finalized there is no point in optimizing it yet, however these findings are very useful and will teach us to avoid making the same mistakes.

So I looked what was next in the profile… things started to become a bit less evident: if I was a serious person I should have fixed the statusbar issue and remeasured in order to get a better signal to noise ratio, but… ;)
Anyway, I spotted gtk_text_iter_forward_to_line_end taking up a few percents, which looked a bit strange. The first question was: “what has forward_to_line_end to do with search and replace?”. It turned out that GtkSourceView uses it to deal with line markers: fair enough.
So the next step was coming up with a simple test case: the easiest thing to do was taking a GtkTextBuffer, put a line of text in it and move an iter to the end of the line in a loop 5000000 times (where 5000000 is the number of iterations that made the test case take about one minute). Such a stupid test case worked surprisingly well: profiling it with the awesome sysprof clearly showed the two major offenders: _gtk_text_line_char_byte_to_offset and gtk_text_iter_backward_chars.
Both functions need to deal with obtaining an offset in bytes given an offset in number of characters (each character may be more than one byte in utf8) and both functions used a loop to calculate it: guess what? glib has a function that can do that for us, called g_utf8_offset_to_pointer. Such a simple change, which is just a code cleanup, makes the test case take 40 seconds instead of 67 (according to /usr/bin/time).
I am sure that things could be optimized further or maybe, even better, we could try to speed up g_utf8_offset_to_pointer since it’s used in many other places, but this example shows that you don’t need to be a guru to improve things :)

Apropos of performance… I stumbled in this page on apple developers pages which suggests using fts_* functions (see man fts) to traverse file hierarchies: has any of the nautilus/vfs guys ever looked into them?

770

I forgot to mention that I got a Nokia 770 some time ago: the device is awesome, especially the screen, though I have one dead pixel in the bottom right corner :(
Fortunately is only noticeable when playing marbles fullscreen ;)
I played a bit with the device (xterm, ssh and all the various stuff all other people have already talked about). I also installed scratchbox and whipped up a quick port of glightoff: developing with maemo it’s easy and fun, the only problem I enocuntered was that the svg graphics didn’t work. I need to find some more time to play with it some more.