Re: More testing -- postgres, transactions

2002-10-16 Thread Peter Haworth

On Wed, 16 Oct 2002 14:55:51 +0100, Kate L Pugh wrote:
> On Wed 16 Oct 2002, Peter Haworth <[EMAIL PROTECTED]> wrote:
> > You could test $dbh->err or $dbh->state for more robust checking.
> 
> perldoc DBD::Pg (1.13, the latest version) says that it doesn't
> support the state method yet, and that the err method "returns
> PQresultStatus of the current handle".

It doesn't look like state can ever be supported. Here's a typical generation
of your error message in the backend (there are 4 occurrences, all the same):

   if (XactIsoLevel == XACT_SERIALIZABLE)
  elog(ERROR, "Can't serialize access due to concurrent update");

That's all it does. There's no error code for this specific error (or any
other error).

> >> An alternative would be to always return 0, but that'd mean
> >> flagging an actual error as a conflict, and I'd like to keep those
> >> separate since a conflict isn't really an error.)
> > 
> > It's still an error if you don't retry the transaction.
> 
> I don't think so, at least not in the context of this problem. ...
> I have code that can handle that nicely (tells the user what has happened
> and asks them to merge their changes in manually).

Obviously, what I meant was "if you don't retry or tell the user to retry".

-- 
Peter Haworth   [EMAIL PROTECTED]
"If you do get [computer] case fans, make sure you check out how
 loud they are first, avoid any fans with 'screamer' in the name"
-- Sam Yeung




Re: More testing -- postgres, transactions

2002-10-16 Thread Kate L Pugh

On Tue 15 Oct 2002, Kate L Pugh wrote:
>> -- is that evil?  Relying on DBI to give me the right error message?
 
On Wed 16 Oct 2002, Peter Haworth <[EMAIL PROTECTED]> wrote:
> Yes; error messages will always change in the future.

That's what I thought, but I couldn't figure out another way of doing it :(

> You could test $dbh->err or $dbh->state for more robust checking.

perldoc DBD::Pg (1.13, the latest version) says that it doesn't
support the state method yet, and that the err method "returns
PQresultStatus of the current handle".  I looked up PQresultStatus on
www.postgresql.org and found the following:

 PQresultStatus can return one of the following values:

 * PGRES_EMPTY_QUERY -- The string sent to the backend was empty.
 * PGRES_COMMAND_OK -- Successful completion of a command returning
   no data
 * PGRES_TUPLES_OK -- The query successfully executed
 * PGRES_COPY_OUT -- Copy Out (from server) data transfer started
 * PGRES_COPY_IN -- Copy In (to server) data transfer started
 * PGRES_BAD_RESPONSE -- The server's response was not understood
 * PGRES_NONFATAL_ERROR
 * PGRES_FATAL_ERROR

Which doesn't look too promising in terms of differentiating between
errors caused by a concurrent update failure and other kinds of
errors, and in fact when I tested to see what $dbh->err gave me on a
transaction failure and on a simple typo in the SQL, I got "7" both times.
So that ain't gonna work, unless I'm missing something.

>> An alternative would be to always return 0, but that'd mean
>> flagging an actual error as a conflict, and I'd like to keep those
>> separate since a conflict isn't really an error.)
> 
> It's still an error if you don't retry the transaction.

I don't think so, at least not in the context of this problem.  What I
meant by "conflict" in the above was "checksum not matching up".  See
the additional code at
  http://london.pm.org/pipermail/london.pm/Week-of-Mon-20021014/014345.html

I want to return 0 (not die) if *either* the checksum doesn't match,
*or* the checksum does match, but we can't complete the transaction
(which would signal that another instance has got in there and done a
commit in between us checking the checksum and us writing to the
database).  The latter case isn't an error, because I have code that
can handle that nicely (tells the user what has happened and asks them
to merge their changes in manually).


Kake
-- 
http://www.earth.li/~kake/cookery/ - vegan recipes, now with new search feature
http://grault.net/grubstreet/ - the open-source guide to London
http://www.penseroso.com/ - websites for the fine art and antique trade




Re: Date Overlap testing - Golf?

2002-10-16 Thread Rafiq Ismail (ADMIN)

On Wed, 16 Oct 2002, Simon Wilcox wrote:
> What Roger said.
>
> return 1 unless ( $startTest > $intervalEnd || $endTest < $intervalStart );
I just had one of those "duh," moments.  Thank u.






Re: Books on london.pm.org (was Re: applying patterns)

2002-10-16 Thread Richard Clamp

On Fri, Oct 11, 2002 at 06:01:54PM +0200, Paul Johnson wrote:
> Simon Wistow said:
> 
> > Where would we be if we'd not bothered writing some Matt's Scripts
> > replacments on the assumption that nobody would pick them up. Or
> > written an extensible MLM in Perl on the assumption that despite having
> > whinged about it for ages nobody would actually care.
> 
> 
> Oooh, did I miss something?  Has someone (plural?) written (present
> tense?) a new MLM.

Yes indeedy. Plural, present (and mostly past), and new:
http://siesta.sourceforge.net/

I announced in the week before YAPC::Europe here, so maybe people just
didn't pick up on it.

It needs a few things pulling together for its first release, but it's
all self hosting and stuff.

-- 
Richard Clamp <[EMAIL PROTECTED]>




Re: Date Overlap testing - Golf?

2002-10-16 Thread Simon Wilcox

On Wed, 16 Oct 2002, Rafiq Ismail (ADMIN) wrote:

> 
> On Wed, 16 Oct 2002, Roger Burton West wrote:
> > And you're asking "does any part of Test lie within Interval"?
> >
> > 0 if test.start > interval.end
> > 0 if test.end < interval.start
> > 1 otherwise
> Nah, return true if the two intervals overlap, at all.
> 
> It's just messy looking and I wondered if there way a more tidy way of
> doing this.

What Roger said.

return 1 unless ( $startTest > $intervalEnd || $endTest < $intervalStart );

Test it. Or draw 6 little timeline diagrams and talk through the logic.

Simon.

-- 
"Ciao!"
 






Re: Date Overlap testing - Golf?

2002-10-16 Thread Rafiq Ismail (ADMIN)


On Wed, 16 Oct 2002, Roger Burton West wrote:
> And you're asking "does any part of Test lie within Interval"?
>
> 0 if test.start > interval.end
> 0 if test.end < interval.start
> 1 otherwise
Nah, return true if the two intervals overlap, at all.

It's just messy looking and I wondered if there way a more tidy way of
doing this.





[ANNOUNCE] Social meetings, advance warning.

2002-10-16 Thread Paul Mison

As it's getting a little close to the Christmas party season, it 
seemed like a good idea to book the pub already for both November and 
December meetings. No better alternative having suggested itself, 
these will both be upstairs at the Calthorpe Arms, Gray's Inn Road.

The next social meetings are on Thursday, 7th November and Thursday, 
5th December, with the room available from 6pm.

The next technical meeting is on Thursday, 21st November, with 
speakers and location to be confirmed.

Thanks.
-- 
:: paul
:: we're like crystal





Re: Date Overlap testing - Golf?

2002-10-16 Thread Roger Burton West

On Wed, Oct 16, 2002 at 12:17:14PM +, Rafiq Ismail (ADMIN) wrote:

>1) We actually have $intervalStart and $intervalEnd, marking a period in
>time, where $intervalEnd >= $intervalStart.
>
>2) We also have:
>   $startTest and $startEnd.

And you're asking "does any part of Test lie within Interval"?

0 if test.start > interval.end
0 if test.end < interval.start
1 otherwise

Roger




Re: Date Overlap testing - Golf?

2002-10-16 Thread Rafiq Ismail (ADMIN)



On Wed, 16 Oct 2002, Shevek wrote:

> On Wed, 16 Oct 2002, Rafiq Ismail (ADMIN) wrote:
> This question is underspecified. Two points cannot intersect unless they
> are coincident points. Define the endpoints of your ranges. I'm assuming
> that date_a and date_b are just point dates.
Indeed, however I did under specify (see below).

> > (,mm?,dd?) and turned into days since epoch using Date::Calc which is
> What is the '?'? Is this a regular expression?

This bit is unimportant, since the dates are converted to epoch first.

> > We can do it with three tests on the boundaries, however I'm curious if it
> What boundaries?

1) We actually have $intervalStart and $intervalEnd, marking a period in
time, where $intervalEnd >= $intervalStart.

2) We also have:
$startTest and $startEnd.

3)
  Is there a more affective way of saying - summarised:
return 1 if (  ($startTest <= $intervalStart &&
$endTest >= $intervalStart)
||
($startTest <= $intervalEnd &&
$endTest >= $intervalEnd)
||
($startTest >= $intervalStart &&
 $endTest <= $intervalEnd)
) );

I think.  It really does my head in.

Cheers,


Rafiq





Re: Date Overlap testing - Golf?

2002-10-16 Thread Shevek

On Wed, 16 Oct 2002, Rafiq Ismail (ADMIN) wrote:

> I want a simple routine which tests date_a against date_b to see if date_a
> intersects in anyway with date_b.  The dates are initially supplied as

This question is underspecified. Two points cannot intersect unless they 
are coincident points. Define the endpoints of your ranges. I'm assuming 
that date_a and date_b are just point dates.

> (,mm?,dd?) and turned into days since epoch using Date::Calc which is

What is the '?'? Is this a regular expression?

> already used else where, so we're not using Date::Calc specifically for
> this.
> 
> We can do it with three tests on the boundaries, however I'm curious if it

What boundaries?

> can be done in fewer?  Elegence?

Proofs for the smallest time you can do this by comparison will probably 
look like a tree of possibilities, number of cases is the number of 
leaves. Depth of the tree is time, which is log(number of cases). Those 
who have seen this construction before will understand what I'm talking 
about. Noone else will because my explanation is so crap.

However, if you add the missing info, I can help more.

S.

-- 
Shevek
I am the Borg.

sub AUTOLOAD{my$i=$AUTOLOAD;my$x=shift;$i=~s/^.*://;print"$x\n";eval
qq{*$AUTOLOAD=sub{my\$x=shift;return unless \$x%$i;&{$x}(\$x);};};}

foreach my $i (3..65535) { &{'2'}($i); }






Re: Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread Shevek

On Wed, 16 Oct 2002, the hatter wrote:

> On Wed, 16 Oct 2002, Shevek wrote:
> 
> > > Benchmark: timing 10 iterations of classneg, nongreedy...
> > >   classneg:  3 wallclock secs ( 4.30 usr +  0.00 sys =  4.30 CPU) @
> > > 23255.81/s (n=10)
> >
> > How can you get 4.30 usr secs into 3 wallclock secs?
> 
> 2 CPUs ?

One thread.

S.

-- 
Shevek
I am the Borg.

sub AUTOLOAD{my$i=$AUTOLOAD;my$x=shift;$i=~s/^.*://;print"$x\n";eval
qq{*$AUTOLOAD=sub{my\$x=shift;return unless \$x%$i;&{$x}(\$x);};};}

foreach my $i (3..65535) { &{'2'}($i); }






Re: HTML::Template ramblings

2002-10-16 Thread nemesis

Mark Fowler wrote:
> On Wed, 16 Oct 2002, nemesis wrote:
> 
> 
>>If I preload Page.pm and have a BEGIN {} block in it that loads the
>>template file into a variable for use within the module, would this
>>BEGIN block get run when the module was use'ed, some other time, or not
>>at all?
> 
> 
> Right, this is where I explain what BEGIN time is.

Thanks a lot for the information, that clears a few things up.

Will





Re: HTML::Template ramblings

2002-10-16 Thread nemesis

Leon Brocard wrote:
> nemesis sent the following bits through the ether:
> 
> 
>>I guess that every time this method is called HTML::Template reads in the 
>>the template file from disk.  I think this could be faster if the template 
>>was in memory.
> 
> 
> The docs at
> http://search.cpan.org/author/SAMTREGAR/HTML-Template-2.6/Template.pm
> point out that you should set cache => 1 in the constructor in order
> to cache templates. For preloading templates, see "Q: How can I
> pre-load my templates using cache-mode and mod_perl?". Make sure to
> benchmark to see if it really makes a difference.

Aaaah, thanks for that, very useful :-)

Will.





Date Overlap testing - Golf?

2002-10-16 Thread Rafiq Ismail (ADMIN)

This is an easy one, but there has to be some standard for doing it; which
is what I'm curious about.

I want a simple routine which tests date_a against date_b to see if date_a
intersects in anyway with date_b.  The dates are initially supplied as
(,mm?,dd?) and turned into days since epoch using Date::Calc which is
already used else where, so we're not using Date::Calc specifically for
this.

We can do it with three tests on the boundaries, however I'm curious if it
can be done in fewer?  Elegence?

Cheers,

R.






Re: regex - split on one line

2002-10-16 Thread Alex McLintock


>On Tue, Oct 15, 2002 at 01:29:11PM -0400, Chris Devers wrote:
> > ?name=fred;age=24;favorite_color=3
> >
>
>Nicholas Clark
>IIRC semicolons are legal before any query string -


They are frequently used to introduce the session id, particularly with 
Java servlet systems...

Dunno why...

Alex




Openweb Analysts Ltd, London.
Software For Complex Websites http://www.OWAL.co.uk/
Open Source Software Companies please register here 
http://www.OWAL.co.uk/oss_support/





Re: HTML::Template ramblings

2002-10-16 Thread nemesis

Tim Sweetman wrote:
> nemesis wrote:
> 
>>I guess that every time this method is called HTML::Template reads in the the
>>template file from disk.  I think this could be faster if the template was in
>>memory.
> 
> 
> Um, RTFM on HTML::Template, which describes its "cache" option. There's
> also an XS- or Inline-retrofitted HTML::Template on the CPAN, if memory
> serves, which does something outrageous like turning templates into bits
> of C and compiling them - which is also outrageously fast.

/me peers more closely at the docs

If used in a constructor wouldn't cache => 1 just cache for the life of the 
httpd thread, and not for the whole server?  Sorry if this is obvious, I have 
only just started doing mod_perl.

Will.





Re: HTML::Template ramblings

2002-10-16 Thread Mark Fowler

On Wed, 16 Oct 2002, nemesis wrote:

> If I preload Page.pm and have a BEGIN {} block in it that loads the
> template file into a variable for use within the module, would this
> BEGIN block get run when the module was use'ed, some other time, or not
> at all?

Right, this is where I explain what BEGIN time is.  BEGIN time is the time
when perl does it's initial sweep over the module as it's working out
what's actually there.  It's the bit where perl looks for syntax errors in
your code etc. Blocks that you define with BEGIN, or are inherently BEGIN
(like all "use"  statements) get called straight away...before you even 
check the code below.

"use" statements happen at BEGIN time as you often need to load the code 
that you are using to prevent compile time problems in the rest of the 
code that you are parsing after the use statement.

So, when you "use Page;" then, as a use statement it switches files and
starts running over the code in Page.pm.  All this happens in BEGIN time
for your original code, but there's a separate BEGIN time stage and
run-time-time stage for Page.pm which all happens as that code is parsed 
(BEGIN time) and then executed (run-time-time) before the rest of your 
original code is run.

*phew*

Back to the original problem.  You want to load Page.pm or whatever in 
your startup.pl (or again, whereever) and have it load in the file once 
before forking so that a) it doesn't have to load it every time and b) you 
have one copy in memory.

So the answer is yes, you could defined a BEGIN block in Page.pm that
loaded the page and stuck it in a global variable and everything would run
fine, but you don't have to and it's probably bad form.  Instead, you
should just stick this code in the main body of your module as all this
code will be executed in the BEGIN time of startup.pl

Make sense?

Mark.

(Please note that this is a broad description and may fudge over some 
details in an attempt at clarity.)

-- 
s''  Mark Fowler London.pm   Bath.pm
 http://www.twoshortplanks.com/  [EMAIL PROTECTED]
';use Term'Cap;$t=Tgetent Term'Cap{};print$t->Tputs(cl);for$w(split/  +/
){for(0..30){$|=print$t->Tgoto(cm,$_,$y)." $w";select$k,$k,$k,.03}$y+=2}





Re: HTML::Template ramblings

2002-10-16 Thread Leon Brocard

nemesis sent the following bits through the ether:

> I guess that every time this method is called HTML::Template reads in the 
> the template file from disk.  I think this could be faster if the template 
> was in memory.

The docs at
http://search.cpan.org/author/SAMTREGAR/HTML-Template-2.6/Template.pm
point out that you should set cache => 1 in the constructor in order
to cache templates. For preloading templates, see "Q: How can I
pre-load my templates using cache-mode and mod_perl?". Make sure to
benchmark to see if it really makes a difference.

HTH, Leon
-- 
Leon Brocard.http://www.astray.com/
scribot.http://www.scribot.com/

... Error 256: Programmer Deleted




RE: Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread Clayton, Nik [IT]

> > > Benchmark: timing 10 iterations of classneg, nongreedy...
> > >   classneg:  3 wallclock secs ( 4.30 usr +  0.00 sys =  
> 4.30 CPU) @
> > > 23255.81/s (n=10)
> >
> > How can you get 4.30 usr secs into 3 wallclock secs?
> 
> 2 CPUs ?

Not on the box I'm running the benchmarks on.

# psrinfo
0on-linesince 10/13/02 01:00:55

N
-- 
11 2 3 4 5 6 77
 0 0 0 0 0 0 05
  -- The 75 column-ometer
 Contributing to the heat death
Global Messaging, 120 Cheapside, x83331  of the universe since 1973.




Re: HTML::Template ramblings

2002-10-16 Thread Tim Sweetman

nemesis wrote:
> I guess that every time this method is called HTML::Template reads in the the
> template file from disk.  I think this could be faster if the template was in
> memory.

Um, RTFM on HTML::Template, which describes its "cache" option. There's
also an XS- or Inline-retrofitted HTML::Template on the CPAN, if memory
serves, which does something outrageous like turning templates into bits
of C and compiling them - which is also outrageously fast.

Cheers

Tim




HTML::Template ramblings

2002-10-16 Thread nemesis

Hi all,

I have mod_perl running and I am pre-loading the HTML::Template module (among 
others) when Apache starts up.  I also have a self written Page.pm module with 
the 'print' method and uses the HTML::Template module to do substitutions in a 
template file:

sub print {
 my $self = shift;
 my $template = HTML::Template->new(filename => $self->{'_template_name'},
 path => [$self->{'_path_to_templates'}]
 );

#more perl code...
}

I guess that every time this method is called HTML::Template reads in the the 
template file from disk.  I think this could be faster if the template was in 
memory.  I don't want to hard code the template into Page.pm to avoid the disk 
access, as it would make maintaining the template difficult.  If I preload 
Page.pm and have a BEGIN {} block in it that loads the template file into a 
variable for use within the module, would this BEGIN block get run when the 
module was use'ed, some other time, or not at all?

This is the only method I have thought of so far, will it work?  Does anyone 
have a better idea than this?

Thanks
Will.





Re: Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread Leon Brocard

Clayton, Nik [IT] sent the following bits through the ether:

> Personally, I almost always use a non-greedy match.  But I wonder if
> there's something subtle I've been missing.

In most cases there won't be much of a difference. However, for far
more than you could possibly want to know about the subject, I highly
recommend the second edition of Mastering Regular Expressions. It's
almost a complete rewrite and compares the regex engines of lots of
different languages too (oh, and Unicode). It is a great book.

Leon

ps it's quite a good book
-- 
Leon Brocard.http://www.astray.com/
scribot.http://www.scribot.com/

... MRE2 is a good book




Re: Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread the hatter

On Wed, 16 Oct 2002, Shevek wrote:

> > Benchmark: timing 10 iterations of classneg, nongreedy...
> >   classneg:  3 wallclock secs ( 4.30 usr +  0.00 sys =  4.30 CPU) @
> > 23255.81/s (n=10)
>
> How can you get 4.30 usr secs into 3 wallclock secs?

2 CPUs ?


the hatter






Re: regex - split on one line

2002-10-16 Thread Peter Haworth

On Tue, 15 Oct 2002 13:29:11 -0400 (EDT), Chris Devers wrote:
> So potentially, semi-colons can show up in a legal URL. I can't remember
> ever seeing this behavior in the wild, but apparently it's kosher, and if
> you ever do see it then semi-colons won't work as a separator here.

I use them quite a lot. The point being that HTML containing ampersand
separated query arguments should really use '&' rather than '&' to be
unambiguous, but some browsers don't get that right. ';' is easier to read
than '&'.

-- 
Peter Haworth   [EMAIL PROTECTED]
"Your question doesn't make any sense. You might as well ask whether
 it is possible to grow vegetables from a painting, without becoming
 Wednesday first."  -- Abigail, c.l.p.misc




Re: Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread Shevek

On Wed, 16 Oct 2002, Clayton, Nik [IT] wrote:

> s~(.*?):(.*?)~...~

This is slower.

> s~([^:]*):([^<]*)~...~

This is faster.

> Benchmark: timing 10 iterations of classneg, nongreedy...
>   classneg:  3 wallclock secs ( 4.30 usr +  0.00 sys =  4.30 CPU) @
> 23255.81/s (n=10)

How can you get 4.30 usr secs into 3 wallclock secs?

>  nongreedy:  5 wallclock secs ( 5.29 usr +  0.00 sys =  5.29 CPU) @
> 18903.59/s (n=10)
>  Rate nongreedy  classneg
> nongreedy 18904/s--  -19%
> classneg  23256/s   23%--

Someone who knows more internals will explain why I'm wrong.

Someone who knows more internals will also explain why when you have a DFA 
representation it is not possible to transform a nongreedy match into 
something where the transition for the character(s) following the 
nongreedy match are added as extra outgoing transitions from the atom 
inside the * operator.

When given the choice between working it out and asking a mailing list ...

S.

-- 
Shevek
I am the Borg.

sub AUTOLOAD{my$i=$AUTOLOAD;my$x=shift;$i=~s/^.*://;print"$x\n";eval
qq{*$AUTOLOAD=sub{my\$x=shift;return unless \$x%$i;&{$x}(\$x);};};}

foreach my $i (3..65535) { &{'2'}($i); }






Re: More testing -- postgres, transactions

2002-10-16 Thread Peter Haworth

On Tue, 15 Oct 2002 18:55:06 +0100, Kate L Pugh wrote:
> if ($@) { 
> my $error = $@; 
> $dbh->rollback; 
> $dbh->{AutoCommit} = 1; 
> if ($error =~ /Can't serialize access due to concurrent update/) { 
> return 0; 
> } else { 
> croak $error; 
> } 
> 
> -- is that evil?  Relying on DBI to give me the right error message?

Yes; error messages will always change in the future. You could test $dbh->err
or $dbh->state for more robust checking. Just remember to grab it before you
do anything else with $dbh, like rollback.

> Note this is in the code, not the test.  An alternative would be to
> always return 0, but that'd mean flagging an actual error as a
> conflict, and I'd like to keep those separate since a conflict isn't
> really an error.)

It's still an error if you don't retry the transaction. This is why I don't
like serialised transactions - they require too much extra work. Of course,
for some scenarios they're essential, but I don't have any of those.

-- 
Peter Haworth   [EMAIL PROTECTED]
"f y cn rd ths y mst hv bn sng nx"




Non-greedy matches versus class negation (was: RE: regex - split on one line)

2002-10-16 Thread Clayton, Nik [IT]

Paul Makepeace wrote this snippet.

> $html =~ s~([^:]*):(.*?)~$2~gi;

Interesting mix.  Why not write either:

s~(.*?):(.*?)~...~

(non-greedy match) or

s~([^:]*):([^<]*)~...~

(negating a character class).  Is this just a matter of personal 
preference, or is there some advantage to using one over the other 
(when it's a choice between 'use Benchmark' and 'post to a mailing list'
the mailing list wins every time :-) ).

Personally, I almost always use a non-greedy match.  But I wonder if
there's something subtle I've been missing.

N

PS: Oh, alright.

#!/opt/perl/5.6.1/bin/perl -w

use strict;
use Benchmark qw(cmpthese);

my $data = 'mumble www.foo.com:a description mumble';
my $foo;

cmpthese(100_000, { nongreedy => \&nongreedy, 
classneg  => \&classneg });

sub nongreedy {
$foo = $data;
$foo =~ s~(.*?):(.*?)~$2~gi
}

sub classneg {
$foo = $data;
$foo =~ s~([^:]*):([^<]*)~$2~gi
}

__END__

Benchmark: timing 10 iterations of classneg, nongreedy...
  classneg:  3 wallclock secs ( 4.30 usr +  0.00 sys =  4.30 CPU) @
23255.81/s (n=10)
 nongreedy:  5 wallclock secs ( 5.29 usr +  0.00 sys =  5.29 CPU) @
18903.59/s (n=10)
 Rate nongreedy  classneg
nongreedy 18904/s--  -19%
classneg  23256/s   23%--

Well, you learn something new every day.
-- 
11 2 3 4 5 6 77
 0 0 0 0 0 0 05
  -- The 75 column-ometer
 Contributing to the heat death
Global Messaging, 120 Cheapside, x83331  of the universe since 1973.