Re: My CPU Hates Me




On Jul 6, 2007, at 1:44 PM, Jim Clark wrote:

Ari Brown wrote:
Pattern matching problem. This time, it doesn't print out any thing and just soaks up my CPU. I tried slowly adding more and more for it to do, and it worked great -- until TABLE7. Then it just soaks up my CPU and makes me cry. At first, when nothing was printing, I added $stdout.flush to make it print. But it didn't print! This makes me think that it's something in the when part.

Whats going on?

Help!


lines.each do |line|
case line
when / ^"(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*) ","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.* )","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(.*)","(. *)","(.*)","(.*)"$/
There are several ways to optimize the regular expression but the most important thing is to not be greedy. What I mean by this is that using (.*) matches everything to the end of the line and then the regular expression backtracks to find the next " character specified. It will choose the " character closest to the end of the line but that is not the one you want so it backtracks again and again and so on wasting CPU cycles.

Instead of being greedy and using "(.*)", your best bet would be to use "([^"]*)". This assumes that there are no " characters within each field. This stops the regex from getting past the next " character of each field and eliminates all that backtracking.

Alternatively, you could look at splitting the line on the comma (see http://www.ruby-doc.org/core/classes/String.html#M000818) and end up with a nice array to reference each field. You'll still have the quotes that you'll need to strip from each item (unless you use the three character separator of "," and manually remove the leading " character from the first element and the trailing " character from the last element). This will likely be the fastest way since the regex doesn't need to be evaluated. However, you may need to put in more logic if not all lines are to be split in the text file such as comment lines.

Regards,
Jim
Ari also check out Unit Testing in any of the Ruby books. You can test your regex for failures as you go. Regex is one of those instances where UT is really immediately and obviously useful. (tho UT is truthfully useful all the time)

Also, sometimes reading giant files, even if you use readline or another way to break it into smaller parts to work with, you should consider reading x bytes of the file at a time. (you can add a routine to check where the last \n appeared before x bytes and then use the location (in bytes) of the last \n to rewind the file to and start reading again for x bytes more or until end of file.

RegEx is great but will become a big resource hog if you just let it go on a big file. Chop it up into smaller tasks, and you can report on the progress of the whole process.

John Joyce

.



Relevant Pages

  • Re: My CPU Hates Me
    ... Then it just soaks up my CPU and makes me cry. ... What I mean by this is that using matches everything to the end of the line and then the regular expression backtracks to find the next " character specified. ...
    (comp.lang.ruby)
  • Re: Hub transport regex is broken, a horrible implementation, or Im an idiot.
    ... grep, egrep, and perl - all of which use a standard regex ... occurrences of the preceding character. ... I don't know which regex engine they use, ... organization' predicate, I can already tell you it won't work thanks ...
    (microsoft.public.exchange.admin)
  • Re: In Find and Replace: How To Find Any Combination Of Characters
    ... When I use wildcards, Word can¹t search for certain items. ... As for RegEx, ... It helps greatly to have a very accurate and definitive "problem statement" ... matches any single character, but only ONE character in the ...
    (microsoft.public.mac.office.word)
  • Re: Parsing large web server logfiles efficiently
    ... I wanted you to take out the regex ... 12.5% of the CPU. ... If not, then it probably not CPU bound, but rather ... > This script runs parallely for all 8 files. ...
    (comp.lang.perl.misc)
  • Re: In Find and Replace: How To Find Any Combination Of Characters
    ... Are you naming Word Help "online help" below? ... would you please give me a lead to an explanation of RegEx. ... When I use wildcards, Word can¹t search for certain items. ... matches any single character, but only ONE character in the ...
    (microsoft.public.mac.office.word)