Saturday, February 5, 2011

Slow scrolling / high CPU usage with spaces-at-end-of-line syntax highlighting

I'm using the SpaceHi plugin to highlight spaces at the end of lines
and tabs anywhere in my files. As far as I can tell, this plugin just
enables two syntax rules:

syntax match spacehiTab /\t/ containedin=ALL
syntax match spacehiTrailingSpace /\s\+$/ containedin=ALL

I've found that when I have these syntax rules enabled, Vim
occasionally gets into a state where it scrolls very slowly. That is,
ctrl+e will lock up Vim and spin my CPU for a second or two. When I
disable these syntax rules, Vim is responsive once again, and when I
re-enable the rules, Vim again becomes unresponsive.

It might be my imagination, but I think I hit this problem only when
I've had Vim open for a long time (at least a few hours, maybe a few
days). Scrolling is only slow in files which have tabs or trailing
whitespace, but as far as I can tell, I don't have the same problem
after I restart Vim and open the same files. The files are entirely
ASCII, and I've encountered this problem with both large (10k line)
and small (100 line) files. They've mostly been C/C++ files, although
I believe I encountered the problem with a plain-text file once.

I caught this behavior inside perf, but unfortunately my Vim was
compiled without debugging symbols, so I didn't get a useful trace.
I've since compiled version 7.3.112 from hg with debugging symbols,
but I haven't been able to reproduce the problem with either binary
since.

I was able to reproduce something which seemed similar to the problem
above by creating a line with about 1000 trailing space characters.
(Of course when I actually encounter this problem, it's on less
pathological files.) I've attached the perf report below. This is at
least superficially similar to the perf report I got when I profiled
my system's vim -- it has two Vim routines, followed by two libc
routines, followed by more vim routines.

It seems to me that Vim should have no trouble matching 1000 spaces at
the end of a line. Seeing as I can't reproduce on command the issue I
care about, I was hoping to at least get some help with the file with
the trailing spaces. Perhaps the solution is as simple as tweaking
the syntax rules.

I'd really appreciate any help with this.

Regards,
-Justin

-----

$ uname -a
Linux jlebar-laptop 2.6.35-25-generic #44-Ubuntu SMP Fri Jan 21
17:40:44 UTC 2011 x86_64 GNU/Linux

-----

~/vim/src$ hg sum
parent: 2694:fcea35e2a41f tip
updated for version 7.3.112

Output of compiling vim with -g -O2 -fno-omit-frame-pointer, then running

$ perf record -g vim file-with-lots-of-spaces

and scrolling around, then running

$ perf report.

I find it awfully strange that utfc_ptr2len shows up as the hottest
function, considering how little it actually does when fed ASCII text.

28.10% vim vim [.] utfc_ptr2len
|
--- utfc_ptr2len
|
|---11.10%-- regrepeat
| regtry
| vim_regexec_both
| vim_regexec_multi
| syn_regexec
| syn_current_attr
| get_syntax_attr
| win_update
| update_screen
| ins_redraw
| edit
| invoke_edit
| normal_cmd
| main_loop
| main
| __libc_start_main
|
|--36.30%-- regtry
| vim_regexec_both
| vim_regexec_multi
| syn_regexec
| syn_current_attr
| get_syntax_attr
| win_update
| update_screen
| ins_redraw
| edit
| invoke_edit
| normal_cmd
| main_loop
| main
| __libc_start_main
--0.10%-- [...]

23.93% vim vim [.] regrepeat
|
--- regrepeat
|
|--12.16%-- regtry
| vim_regexec_both
| vim_regexec_multi
| syn_regexec
| syn_current_attr
| get_syntax_attr
| win_update
| update_screen
| ins_redraw
| edit
| invoke_edit
| normal_cmd
| main_loop
| main
| __libc_start_main
--0.12%-- [...]

21.96% vim libc-2.12.1.so [.] 0x00000000086f4c
|
--- 0x7f0e136d5f8c

| (snipped callers, all address only.)

9.99% vim libc-2.12.1.so [.] memset
|
--- memset
ga_grow
push_current_state
push_next_match
syn_current_attr
get_syntax_attr
win_update
update_screen
ins_redraw
edit
invoke_edit
normal_cmd
main_loop
main
__libc_start_main

7.43% vim vim [.] syn_current_attr
|
--- syn_current_attr
|
|--99.87%-- get_syntax_attr
| win_update
| update_screen
| ins_redraw
| edit
| invoke_edit
| normal_cmd
| main_loop
| main
| __libc_start_main
--0.13%-- [...]

----

Output of vim --version for system vim:

VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Sep 28 2010 11:02:36)
Included patches: 1-330
Compiled by buildd@
Huge version with GTK2-GNOME GUI. Features included (+) or not (-):
+arabic +autocmd +balloon_eval +browse ++builtin_terms +byte_offset +cindent
+clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments
+cryptv +cscope +cursorshape +dialog_con_gui +diff +digraphs +dnd -ebcdic
+emacs_tags +eval +ex_extra +extra_search +farsi +file_in_path +find_in_path
+float +folding -footer +fork() +gettext -hangul_input +iconv +insert_expand
+jumplist +keymap +langmap +libcall +linebreak +lispindent +listcmds +localmap
+menu +mksession +modify_fname +mouse +mouseshape +mouse_dec +mouse_gpm
-mouse_jsbterm +mouse_netterm -mouse_sysmouse +mouse_xterm +multi_byte
+multi_lang -mzscheme +netbeans_intg -osfiletype +path_extra +perl +postscript
+printer +profile +python +quickfix +reltime +rightleft +ruby +scrollbind
+signs +smartindent -sniff +startuptime +statusline -sun_workshop +syntax
+tag_binary +tag_old_static -tag_any_white +tcl +terminfo +termresponse
+textobjects +title +toolbar +user_commands +vertsplit +virtualedit +visual
+visualextra +viminfo +vreplace +wildignore +wildmenu +windows +writebackup
+X11 -xfontset +xim +xsmp_interact +xterm_clipboard -xterm_save
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
user exrc file: "$HOME/.exrc"
system gvimrc file: "$VIM/gvimrc"
user gvimrc file: "$HOME/.gvimrc"
system menu file: "$VIMRUNTIME/menu.vim"
fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_GTK
-pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include
-I/usr/include/atk-1.0 -I/usr/include/cairo
-I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0
-I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0
-I/usr/lib/glib-2.0/include -I/usr/include/pixman-1
-I/usr/include/freetype2 -I/usr/include/libpng12 -DORBIT2=1 -pthread
-D_REENTRANT -I/usr/include/libgnomeui-2.0 -I/usr/include/libart-2.0
-I/usr/include/gconf/2 -I/usr/include/gnome-keyring-1
-I/usr/include/libgnome-2.0 -I/usr/include/libbonoboui-2.0
-I/usr/include/libgnomecanvas-2.0 -I/usr/include/gtk-2.0
-I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gnome-vfs-2.0
-I/usr/lib/gnome-vfs-2.0/include -I/usr/include/orbit-2.0
-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include
-I/usr/include/libbonobo-2.0 -I/usr/include/bonobo-activation-2.0
-I/usr/include/libxml2 -I/usr/include/pango-1.0
-I/usr/include/gail-1.0 -I/usr/include/freetype2
-I/usr/include/atk-1.0 -I/usr/lib/gtk-2.0/include -I/usr/include/cairo
-I/usr/include/gio-unix-2.0/ -I/usr/include/pixman-1
-I/usr/include/libpng12 -Wall -g -O2 -D_REENTRANT -D_GNU_SOURCE
-DDEBIAN -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -I/usr/lib/perl/5.10/CORE
-I/usr/include/python2.6 -pthread -I/usr/include/tcl8.4
-D_REENTRANT=1 -D_THREAD_SAFE=1 -D_LARGEFILE64_SOURCE=1
-I/usr/lib/ruby/1.8/x86_64-linux
Linking: gcc -L. -Wl,-Bsymbolic-functions -rdynamic
-Wl,-export-dynamic -Wl,-E -Wl,--as-needed -o vim -pthread
-lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0
-lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpng12 -lpango-1.0
-lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt
-lglib-2.0 -lgnomeui-2 -lbonoboui-2 -lgnomevfs-2 -lgnomecanvas-2
-lgnome-2 -lpopt -lbonobo-2 -lbonobo-activation -lORBit-2 -lart_lgpl_2
-lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgio-2.0 -lpangoft2-1.0
-lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype
-lfontconfig -lpng12 -lgconf-2 -lgmodule-2.0 -lgobject-2.0
-lgthread-2.0 -lrt -lglib-2.0 -lXt -lncurses -lselinux -lacl -lgpm
-Wl,-E -fstack-protector -L/usr/local/lib -L/usr/lib/perl/5.10/CORE
-lperl -L/usr/lib/python2.6/config -lpython2.6 -lutil -Xlinker
-export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions -L/usr/lib -ltcl8.4
-lieee -lruby1.8 -lrt -lm

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

No comments: