GNOME Bugzilla – Bug 317125
Deleting big range of text with tags in GtkTextBuffer is incredibly slow
Last modified: 2011-02-04 16:19:59 UTC
Attached is a test case demonstrating the problem. If a big buffer has tags applied in many places (there are about 70 tags in total, and the buffer is 9000 lines long, in this test case), then deleting range of text is incredibly slow - in attached test case it takes minutes. It's not really clear what 'big' and 'lot' mean. Attached test case is a dump of real text buffer with syntax highlighting inside. With some highlighting, deleting is not that slow; with some highlighting it is. I.e. just size of buffer and just number of places where tags are applied does not necessarily lead to slow deletion. But I could not track it down to something meaningful. Interesting thing is that removing tags from buffer before deleting makes things fast - it takes seconds. To see this, change '#if 0' to '#if 1' in the source. To reproduce: 1) compile attached file; 2) run it; 3) press ctrl-a to select all, and press backspace. Result: it freezes for minutes. It reproduces in gtk-2.6.4 and gtk from gtk-2-8 cvs branch.
Created attachment 52602 [details] Test case. It's big
I ran sysprof of muntyan's testcase, since he doesn't have a kernel > 2.6.11 Here is the dump and a png showing the bottleneck (at least according to sysprof)
Created attachment 52603 [details] profile.txt
Created attachment 52604 [details] profile.png
Created attachment 53247 [details] [review] a patch Can you see if the attached patch helps ? It should eliminate the quadratic behaviour (in the number of deleted tags)
Yes, it does help. I tried big files I have here, and everything worked fine. Speed is about the same as speed of deleting all tags, i.e. it's great.
just to confirm, works here too and I haven't noticed bugs/regressions
2005-10-11 Matthias Clasen <mclasen@redhat.com> * gtk/gtktextbtree.c (_gtk_text_btree_delete): Try to match an off toggle here with the matching on toggle if it immediately follows. This is a common case, and handling it here prevents quadratic blowup in cleanup_line() below. (#317125) * gtk/gtktextsegment.h: * gtk/gtktextsegment.c (_gtk_char_segment_new_from_two_strings): Pass the character counts into this function instead of computing them