client_stack(): Only stack windows once per mainloop
I was creating 2000 wiboxes in a loop (don't ask) and creating them took forever. According to callgrind, there were about 2 million calls to xcb_configure_window() and most (if not all) of them were from client_stack(). Awesome spent 70% of its cpu time in these client_stack() calls. client_stack() is O(N^2) on the number of clients (it walks the list of clients itself twice and each call to client_stack_above() walks the list too) and O(N) on the number of wiboxes (it walks the wibox list twice). So obviously calls to it should be rare. This patch makes client_stack() only set a flag which is later checked. This should reduce the number of restacks to the bare minimum. With this patch, neither xcb_configure_window() nor anything else client_stack() related shows up as having a lot of calls or using much cpu time. Signed-off-by: Uli Schlachter <psychon@znc.in> Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
4b82608952
commit
2a6d5d207d
13
client.c
13
client.c
|
@ -344,8 +344,8 @@ client_layer_translator(client_t *c)
|
|||
* \todo It might be worth stopping to restack everyone and only stack `c'
|
||||
* relatively to the first matching in the list.
|
||||
*/
|
||||
void
|
||||
client_stack()
|
||||
static void
|
||||
client_real_stack(void)
|
||||
{
|
||||
uint32_t config_win_vals[2];
|
||||
client_node_t *node, *last = *client_node_list_last(&globalconf.stack);
|
||||
|
@ -400,6 +400,15 @@ client_stack()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
client_stack_refresh()
|
||||
{
|
||||
if (!globalconf.client_need_stack_refresh)
|
||||
return;
|
||||
globalconf.client_need_stack_refresh = false;
|
||||
client_real_stack();
|
||||
}
|
||||
|
||||
/** Manage a new client.
|
||||
* \param w The window.
|
||||
* \param wgeom Window geometry.
|
||||
|
|
8
client.h
8
client.h
|
@ -55,7 +55,6 @@ DO_RCNT(client_t, client, client_delete)
|
|||
|
||||
bool client_maybevisible(client_t *, int);
|
||||
client_t * client_getbywin(xcb_window_t);
|
||||
void client_stack(void);
|
||||
void client_ban(client_t *);
|
||||
void client_unban(client_t *);
|
||||
void client_manage(xcb_window_t, xcb_get_geometry_reply_t *, int, bool);
|
||||
|
@ -79,6 +78,7 @@ void client_focus(client_t *);
|
|||
void client_focus_update(client_t *);
|
||||
void client_unfocus(client_t *);
|
||||
void client_unfocus_update(client_t *);
|
||||
void client_stack_refresh(void);
|
||||
|
||||
int luaA_client_newindex(lua_State *);
|
||||
|
||||
|
@ -86,6 +86,12 @@ int luaA_client_userdata_new(lua_State *, client_t *);
|
|||
|
||||
DO_SLIST(client_t, client, client_unref)
|
||||
|
||||
static inline void
|
||||
client_stack(void)
|
||||
{
|
||||
globalconf.client_need_stack_refresh = true;
|
||||
}
|
||||
|
||||
/** Put client on top of the stack.
|
||||
* \param c The client to raise.
|
||||
*/
|
||||
|
|
2
event.h
2
event.h
|
@ -26,12 +26,14 @@
|
|||
|
||||
#include "wibox.h"
|
||||
#include "layout.h"
|
||||
#include "client.h"
|
||||
|
||||
static inline int
|
||||
awesome_refresh(void)
|
||||
{
|
||||
layout_refresh();
|
||||
wibox_refresh();
|
||||
client_stack_refresh();
|
||||
return xcb_flush(globalconf.connection);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue