GNOME Bugzilla – Bug 712263
efficiency of string replacement
Last modified: 2014-10-12 21:01:56 UTC
in the replacement function has to be a part in code that is very inefficient. If I want to replace a prefix "abc;" in n lines (n > 100) (I tested with "abc;"+n) as text to be diffed against the string "def"), the program requires an inacceptable long time to perform this task while for 20 lines everything works fine. Replacement should work in O(n) and even millions of lines shouldn't take longer than 1 or 2 seconds.
ok, I was wrong, the issue is not reproducible that easy. The number of lines doesn't seem to be related to the time of freeze. The output says: <output> ERROR:dbus.proxies:Introspect error on :1.302:/org/gnome/Meld: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.NoReply: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. </output> But this message appear or doesn't without relation to the freeze.
The following behavior is reproducible and should be a hint helping to fix the issue: 1.) replace text -> freeze 2.) send SIGINT to meld (this doesn't kill meld, but a subprocess): Stack is often (but not always) <output> Traceback (most recent call last):
+ Trace 232763
while self._find_text(0):
buf.move_mark( buf.get_selection_bound(), it ) KeyboardInterrupt </output> 3.) do the same replacement task again (often succeeds) (seems to suceed always if topmost frame on the stack is on line 170)
Sorry for the salami report...
What version of Meld are you running?
I reported the bug with HEAD of master. Now I reproduced it with 1.8.3 (as printed by meld --version). You might want to run <code> for i in range(0,1000): print("abc;"+str(i)) </code> in python and copy the output in a blank file comparison to the left. Then press Strg+H and replace <tt>abc;</tt> with the empty string.
Yeah this is a problem everywhere. The issue is that it's quite difficult to do this efficiently and still maintain a reasonable user experience because of the way we dynamically update diffs. The easy solution is to make any Replace All action run a regex and then set the resulting text as the new text in the buffer. This works, but it's quite unpleasant because some of the UI behaviours are subtly different to what should happen. For example, we have to do a full diff recalculate even if almost nothing changed, and the cursor position gets lost. I'm sure there's a nicer way to do this but I'm not sure what it is.
I think that given the annoyance of fixing this with the current findbar model, I'm just going to declare this to depend on getting the GtkSourceView search usage into Meld, which should happen as soon as we branch for 3.13.
I've moved our replace all handling to use GtkSourceView's SearchContext, and it seems a lot better to me. Not necessarily fast, but it's never going to be just because of the comparisons. If you still see unacceptably long pauses, please feel free to reopen. Thanks for the bug report!
3.12.0 performs very, very good! Thank you!