grizzley has asked for the wisdom of the Perl Monks concerning the following question:
Hi all!
Short introduction: I have to do at work some analysis of a project filled with macros (over 13.000) in such way no one is able to read it anymore, so I decided to write simple Perl script, which takes some C++ code, and does not so complicated find/replace of all macros. It works pretty well, but long. About 30 seconds.
I have got familiar with Devel::NYTProf and it gave a response, that function initDefinesList() is bottleneck. I have isolated it into script below and started further checks. I copied whole function body to the script body and it took only 1s to run. Copied it back to the function - 30s. NYTprof showed, that push @$rresult_list, ... line is consuming 29 out of total 30s, so I commented it out. One more run, and surprisingly my $balloon = genDivBalloon(...) line indicated as guilty. So I removed everything inside while($str =~ /.../) loop and according to next report now this regexp consumes all the time. I have written simple one liner with $str filled and while loop and it takes less than second... Another one liner producing huge hash of hashes - run in miliseconds. So every piece of code separately is running in a blink of eye, together it forms a tortoise.
In __DATA__ section I added few example defines just to show you how it looks like.
Has someone an idea what can be wrong and where?
#!perl use 5.10.0; use re 'eval'; use strict; use warnings; use HTML::Entities qw/encode_entities decode_entities/; use DefineAnalyser; our $parens; $parens = qr{ (?: (?: [^()](?!<_MY_STRING_TO_REPLACE>) )+ | \( (??{$parens}) \) )* }x; sub initDefinesList { my %args = @_; my $filename = $args{-filename}; my $rresult_list; # if(!open FH, $filename) # { # print STDERR "Couldn't open define base($filename): ", $!; # return (); # } # # my $str = join"", <FH>; # close FH; my $str = "#define abc(def) /*sourcepath: abc.h*/\\\n def*2+5\n"x +10000; my $begintime=time; print STDERR "begin:", $begintime, "\n"; while($str =~ /\#define \s+ (?<n>\w+) (?<p>\([^)]*\))? (?<c +>(.*\\\n)*.*\n)/gx) { my ($name, $params, $content) = ($+{n}, $+{p}, $+{c}); if(!defined($params)) { $params='' } $content =~ s/\\\n/\n/g; $content =~ s/^\s+//; $content =~ s/\s+$//; $content =~ s!(/\*sourcepath: .*?\*/)!!; my $source = $1; my @params = $params=~/\w+/g; my $macro_def = $name; my $pattern = "\\b$name\\b"; if(@params>0) { $macro_def .= '('.join(', ', @params).')'; $pattern .= qr{\((?<p>$parens)\)}; } else { $pattern .= qr{(\(\s*\))?}; } my $balloon = genDivBalloon( -divid => $name, -sourcefilename => $source, -macrodefinition => $macro_def, -balloontext => $content ); push @$rresult_list, { source=>$source, name=>$name, params=>[@params], content=>$content, macro_def => $macro_def, pattern => $pattern, balloon => $balloon }; } my $endtime=time; print STDERR "end:", $endtime, "\n"; print STDERR "total time: ", $endtime-$begintime, "\n"; return $rresult_list } sub genDivBalloon { my %args = @_; my ($divid, $sourcefilename, $macro_def, $balloontext) = @args{-di +vid, -sourcefilename, -macrodefinition, -balloontext}; if(!defined $divid) { say STDERR "divid not defined" } if(!defined $sourcefilename) { say STDERR "$divid: sourcefilename not defined" } if(!defined $macro_def) { say STDERR "$divid: macro_def not defined" } if(!defined $balloontext) { say STDERR "$divid: balloontext not defined" } return "<div id=\"$divid\" class=\"balloonstyle\">" . encode_entities($sourcefilename) . "<BR />#define <b>" . $macro_def . "</b> <pre>" . encode_entities($balloontext) . "</pre></div>"; } initDefinesList(-filename => 'all_defines_tidy.txt'); __DATA__ #define _APS_NEXT_COMMAND_VALUE 32768 /*sourcepath: ./src/Res +ource.h*/ #define _APS_NEXT_CONTROL_VALUE 201 /*sourcepath: ./src/Resou +rce.h*/ #define COUNT_STR_LEN_FROM_BSRELAYDATA(start, count) /*sourcepath: . +/src/ImplXX.cpp*/\ count = 0; \ for (i = start; i < bsRelayData.data.length && \ i < bsRelayData.data.MAX_LENGTH_C && \ bsRelayData.data.user_data[i] != 0; i++) \ { \ count++; \ } \ dwCountStart += count+1;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: define analyser - performance problem
by jethro (Monsignor) on Jun 29, 2009 at 11:24 UTC | |
by Marshall (Canon) on Jun 29, 2009 at 13:01 UTC | |
by grizzley (Chaplain) on Jun 30, 2009 at 06:55 UTC | |
by Marshall (Canon) on Jun 30, 2009 at 07:41 UTC | |
by grizzley (Chaplain) on Jun 30, 2009 at 09:02 UTC | |
by grizzley (Chaplain) on Jun 30, 2009 at 06:46 UTC |