From: Robert Klemme Date: 2013-02-22T23:32:01+09:00 Subject: Re: Questionable regex performance when using lazy matching and inverted character classes On Fri, Feb 22, 2013 at 1:21 AM, Tikhon B. wrote: > Robert Klemme wrote in post #1098199: >> On Thu, Feb 21, 2013 at 12:12 PM, Tikhon B. >> wrote: >> You are doing the measurement wrong. You do not only measure matching >> but also creation of the String. Given that fact, all your results >> are moot. > > I actively considered this matter when submitting the post, but in the > end I included the string creating in the test to allow anyone to try > out the example by copying one line. Having a second line which defines a variable or constant isn't really that more inconvenient. > The time necessary for the actual > creation process is negligible; I need to run the string creation ten > thousand times before the result is substantial enough to significantly > affect the numbers I'm getting. Still you are measuring one thing but reasoning about another. > I am not sure what sort of proper and complete tests you are looking > for. Tests which measure exactly the functionality you want to scrutinize not something else. > Regarding the actual slowdown, the issue comes down to the engine > repeating the match from the start for every single "a" in the string, > then failing and trying again with the next letter. Backtracking. > I do not see how a > greedy modifier can help in this situation, and I do not know enough > about the ruby regex engine to comment on the underlying design. Mine was a general statement about issues that can be avoided with greediness modifiers. I didn't say it's the solution to all performance issues of this kind. I had a closer look at your expressions. They are of course artificial to demonstrate the effects of backtracking. I would assume that one would typically write different expressions in real applications, for example, using anchoring which dramatically improves the situation here. $ ruby rx-bm.rb user system total real 0 /(?>a[^b]*b)/ 11.732000 0.000000 11.732000 ( 11.737671) 1 /(?>a[^b]*b)/ 0.015000 0.000000 0.015000 ( 0.003000) 0 /\A(?>a[^b]*b)/ 0.000000 0.000000 0.000000 ( 0.002000) 1 /\A(?>a[^b]*b)/ 0.000000 0.000000 0.000000 ( 0.003000) 0 /(?a[^b]*b)/ 0.016000 0.000000 0.016000 ( 0.012001) 1 /(?a[^b]*b)/ 0.000000 0.000000 0.000000 ( 0.003000) 0 /aa*b/ 11.700000 0.000000 11.700000 ( 11.703670) 1 /aa*b/ 0.000000 0.000000 0.000000 ( 0.002000) 0 /\Aaa*b/ 0.000000 0.000000 0.000000 ( 0.002000) 1 /\Aaa*b/ 0.015000 0.000000 0.015000 ( 0.002000) 0 /(?a[^b]*b)/, 11 /\A(?>a[^b]*b)/, 12 /(?a[^b]*b)/, 13 14 /aa*b/, 15 /\Aaa*b/, 16 /(?