Skip navigation.


Federico has written a little Python script to help with profiling Nautilus. I've been wanting something like this for a while so I tried it on ROX-Filer. Turns out that with Zero Install's 0launch command (completely unoptimised Python) parsing a couple of XML files and searching for the best version, plus the filer's initialisation itself, it takes nearly two seconds to start the filer on my machine. Federico's script produced this plot: (gaps at the left are bad; a long time passed between the marked points in the code) I decided to look at the 0launch part, because I haven't tried optimising that before. I'd thought that parsing the XML using xml.dom would be the slow point (it usually is), but the files were small enough that it didn't cause a problem. What did cause a problem was importing xml.dom. I tried rewriting it to use xml.sax but that didn't help initially, because it turns out that importing xml.sax indirectly imports urllib2 (which is extremely slow). By switching to expat for parsing, moving some imports right next to their point of use (lots of stuff isn't needed unless we actually want to download something), and even removing a couple that just weren't used, I roughly halved the time it takes to run 0launch. Actually choosing the best version doesn't seem to take any noticable time at all! 0launch is used several times when you log in; it runs ROX-Filer, ROX-Session, Wallpaper, NetStat, Pager, Clock, Load and OroboROX on my system. Logging out and back in again gave these results (these are for a warm login; cold booting would take longer, of course, and is really more interesting, but I'm too lazy to keep rebooting):
BeforeAfterAfter also cleaning Xsession.d (see comment)
4.3 s3.8 s3.4 s
4.2 s3.8 s3.4 s
4.4 s3.8 s3.5 s

Timings are in seconds with a stop-watch, from pressing Return on the gdm login screen to the desktop appearing and being ready to use. So, a small but noticable improvement. A bigger improvement is noticable when ROX-Filer is already running (for example, I have zsh set up to open a filer window showing the shell's current directory when I press F12). Here, ROX-Filer doesn't need to initialise fully as it just sends a message to the running copy. This is quicker, so a larger fraction of the time is spent in 0launch and this change makes a more noticable difference.

Future work

ROX-Filer could probably be improved, although it's been optimised before so the speed-ups will be smaller. There's still plenty of scope for optimising 0launch, though. In particular, we could get 0launch to write out the list of chosen versions to a file in the cache (e.g. "When running Edit, use Edit 2.0.0 and ROX-Lib 2.0.2"). Then, we just need to check that the versions are in the cache and that no information about newer versions has turned up. If this was done with a C program, we wouldn't even need to initialise Python except when we needed to recalculate the versions. Just for the speed-up, this probably isn't worth it, but it has the additional advantage that if the file has a stable format then other programs could use it. In particular, you could run 0launch once to select the versions (possibly downloading things from the net and writing to the cache) and then run the program itself without write access to the cache.

Profiling Python

The code given in Federico's blog is for C programs, but it's easily adapted to other languages. Here's a Python version of the logging function:
def program_log(msg): os.access('MARK: 0launch: ' + msg, os.F_OK)
__builtins__.program_log = program_log

Cleaning Xsession.d

Further investigations today revealed a load of cruft in /etc/X11/Xsession.d. I deleted 30xfree86-common_xresources, 90xfree86-common_ssh-agent, 50xfree86-common_determine-startup, 99xfree86-common_start, 55gnome-session_gnomerc, 75dbus-1-utils_dbus-launch.bak, and 60gconf2_merge-tree from my Debian system to get the new third column in the timings table.

The XFree86 ones must be from before I was using the service. The gconf one seems to be for migrating a load of XML files to a new format (which really only needs doing once, not once per login). The gnomerc one might be useful if some users run GNOME.

Syndicate content