-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

today I had some fun with wm_torture[1] thanks to jd_ and I also had some fun
with another profiler[2] for lua which produces callgrind-like files which can
be opened in kcachegrind.

The throughput test was interesting (tests done with awesome 3.2.1 in Xephyr):
Just Xephyr, no WM:  3642.12189  windows per second
Default config:        14.000677 windows per second
My own config:          0.510808 windows per second

So, clearly my config was doing something weird and I had some fun with
callgrind and later with the lua-callgrind thingie from [1]. The result was that
 56% of it's lua-cpu-time (no idea what [1] actually measures) was spent inside
awful.client.setslave().

Here is what happens:

function setslave(c)
    local cls = visible(c.screen)
    for k, v in pairs(cls) do
        c:swap(v)
    end
end

setslave() calls c:swap() once for each visible window. Ok, what does :swap()
do? It is defined in client.c line 1433 and contains some O(N) stuff (N = number
of managed clients) and this interesting snippet:

1457         /* Call hook to notify list change */
1458         if(globalconf.hooks.clients != LUA_REFNIL)
1459             luaA_dofunction(L, globalconf.hooks.clients, 0, 0);

Uhm, ok, it calls into some lua code...
Which code is this?

$ git grep hooks.client | grep '\.lua'
lib/awful/widget/tasklist.lua.in:    hooks.clients.register(u)

(for context: this is in awful.widget.tasklist.new() and u is:
 local u = function () tasklist_update(w, buttons, label, data, widgets) end)

So, each time the "clients" hook is called, each tasklist is updated. This is
fine by itself, but if we come back to awful.client.setslave() (which I happen
to call in my manage hook) this means that for each visible window, the tasklist
is updated once (and according to my callgrind tests from before, drawing all
that text repeatedly is quite expensive).

While I don't think we should optimize for an unrealistic benchmark[3], I wonder
if we can't do better. So, anyone got some ideas what could be done? Does the
innocent-looking (well, it still walks the list of all visible windows...)
really have to be this expensive?

So far, I only thought about moving awful.client.setslave() into the C code, but
that seems to be quite inflexible.
Another way would be adding another need_update-like variable to globalconf,
something like need_hooks_clients_and_also_a_better_name_for_this? ;)

Cheers,
Uli

[1] http://mail.gnome.org/archives/gnome-devel-list/2005-August/msg00014.html
[2] http://jan.kneschke.de/projects/profiling-lua-with-kcachegrind
[3] wm_torture's throughput test measures how long it takes to map 200 windows,
    the latency test even maps 1000 windows (but one after another).
- --
"Do you know that books smell like nutmeg or some spice from a foreign land?"
                                                  -- Faber in Fahrenheit 451
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkoEgNoACgkQABixOSrV99+4+wCffdyKHg+X1yKnWM0yVzn9vfxu
OuwAoNyaNOCohqoWKCGPpsndtHQudnY+
=p5vb
-----END PGP SIGNATURE-----

-- 
To unsubscribe, send mail to [email protected].

Reply via email to