GNOME Bugzilla – Bug 332669
List view is extremely slow in single click mode and leaks X server resources
Last modified: 2006-02-27 15:37:33 UTC
Nautilus list view is painfully slow on my old machine (Athlon 700 MHz). When moving the mouse cursor over list view, nautilus + X server eat 100% CPU (66%/33%) and the underline under the current file name is updated only about 2-3 times per second! Another problem is that simply moving the cursor causes X server to grow (about 10 MiB per 20 seconds in my case)
After looking at strace output and the code I can see a few problems here: 1) list view calls gtk_tree_model_row_changed() on two rows every time the cursor moves to a different row, just to update the underline under the current file name, it causes updating the whole view which is very slow; 2) on every motion_notify_event (many times per second) the following interesting sequence of syscalls gets called: open("/home/cyba/.icons/whiteglass/cursors/hand2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/home/cyba/.icons/whiteglass/index.theme", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/icons/whiteglass/cursors/hand2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/icons/whiteglass/index.theme", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/pixmaps/whiteglass/cursors/hand2", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/pixmaps/whiteglass/index.theme", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/X11R6/lib/X11/icons/whiteglass/cursors/hand2", O_RDONLY) = 24 fstat64(24, {st_mode=S_IFREG|0644, st_size=38740, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ec5000 read(24, "Xcur\20\0\0\0\0\0\1\0\5\0\0\0\2\0\375\377\n\0\0\0L\0\0"..., 4096) = 4096 _llseek(24, 0, [0], SEEK_SET) = 0 read(24, "Xcur\20\0\0\0\0\0\1\0\5\0\0\0\2\0\375\377\n\0\0\0L\0\0"..., 4096) = 4096 read(24, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 read(24, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 4096) = 4096 close(24) = 0 the above is caused by gdk_cursor_new() inside motion_notify_event handler 3) gdk_cursor_new() gets called without the corresponding gdk_cursor_unref() so it leaks GdkCursor on every motion_notify_event! 4) every time the cursor moves to a different row, the following sequence of syscalls gets called tens of times (depending on the number of visible rows): open("/etc/group", O_RDONLY) = 24 fcntl64(24, F_GETFD) = 0 fcntl64(24, F_SETFD, FD_CLOEXEC) = 0 _llseek(24, 0, [0], SEEK_CUR) = 0 fstat64(24, {st_mode=S_IFREG|0644, st_size=1003, ...}) = 0 mmap2(NULL, 1003, PROT_READ, MAP_SHARED, 24, 0) = 0xb7ec5000 _llseek(24, 1003, [1003], SEEK_SET) = 0 munmap(0xb7ec5000, 1003) = 0 close(24) = 0 open("/etc/passwd", O_RDONLY) = 24 fcntl64(24, F_GETFD) = 0 fcntl64(24, F_SETFD, FD_CLOEXEC) = 0 _llseek(24, 0, [0], SEEK_CUR) = 0 fstat64(24, {st_mode=S_IFREG|0644, st_size=2375, ...}) = 0 mmap2(NULL, 2375, PROT_READ, MAP_SHARED, 24, 0) = 0xb7ec5000 _llseek(24, 2375, [2375], SEEK_SET) = 0 munmap(0xb7ec5000, 2375) = 0 close(24) = 0 the above is related to getgrgid() and getpwuid() calls and may take a long time if /etc/passwd is a huge file. Both getgrgid() and getpwuid() are called when GtkTreeView requests data from the model. The interesting part is that they get called even if owner/group columns are disabled in the nautilus preferences (which is the default).
Created attachment 60172 [details] [review] This patch fixes 1), 2) and 3) from my comment above. See ChangeLog entry for details.
Created attachment 60173 [details] [review] This patch fixes part of 4) from my comment above (avoids getting data for invisible rows). See ChangeLog entry for details.
Created attachment 60175 [details] [review] This patch fixes the rest of 4) from my comment above (caches results of getpwuid/getgrgid). See ChangeLog entry for details.
All in cvs now. Thanks a lot for these great patches!