Radoslaw Zielinski writes:
> Justin Mason <[EMAIL PROTECTED]> [17-07-2006 15:10]:
> > Radoslaw Zielinski writes:
> >> [EMAIL PROTECTED] <[EMAIL PROTECTED]> [14-07-2006 12:34]:
> [...]
> >>> bug 4777: evalstr version of run_eval_tests, thanks Michael
> [...]
> >> Whoa, that's a hackish one.  Wouldn't storing references to anonymous
> >> subs be better (maybe with help of an AUTOLOAD)?  Modifying namespace
> >> at run time is sooo far from OO...  And situation where foo->can("x")
> >> is true, but foo->x() throws an exception...  That's just plain wrong.
> > Yep -- it would be nicer.  Sadly, last time I checked, it was faster this
> > way, and that's the #1 priority for these methods.  The overhead
> 
> So, correct output is #2 and lack of memory leaks at mere #3...? ;-)

oh, definitely ;)

> > of dereferencing the subroutine is just enough to cause a slowdown.
> 
> > For a demonstration, see "bench_subs" at
> > http://taint.org/xfer/2006/bench_subs.txt --
> 
> >> jm 125...;  ~/ftp/bench/bench_subs
> >                Rate    sub_ref evaled_sub
> > sub_ref    568181/s         --       -11%
> > evaled_sub 641024/s        13%         --
> > 4499991 4499991
> 
> I'll take a look later; now, judging from the rates, you're comparing
> just the calling time; probably way smaller than execution time.

Yes.

> Let's assume SA is really fast (so this optimization actually does
> matter) and processes an average message in 0.1 second.  Assuming (I
> don't feel like digging around there now) this code is called...  well,
> let's be generous: 1000 times per message, so for the sub_ref it takes
> 1000/568181 = 0.00176s, which makes it 1.76% of time spent processing a
> message.  But, since evaled_sub is 13% faster, it saves us, like,
> 0.00176 - (1000/641024) = 0.0002s!  For every message!  That means
> (unless I have messed something up while calculating this) you can
> process 501 messages instead of 500 in a period of time!
> 
> Awesome, I like benchmarks; say, do you have some more?  ;-)

Sure.  But it all adds up -- right now, the biggest hotspot method
(_meta_tests_500) consumes only 2.57% of the time spent.

> > Now, these subs aren't performance-critical, so it would be possible to
> > move to code refs for *these* functions, but leave the body subs (which
> > are generated from the body ruleset and are the most speed-critical part)
> > as namespace-modifying functions. But then we'd have 2 separate methods of
> > doing the same thing and we'd still need that namespace-cleanup code; in
> > my opinion, better to just have just one kludgy method, instead of one
> > elegant *and* one kludgy one. ;)
> 
> Yeah, two would be even uglier.
> 
> [...]
> >>> +  # Some of the rules are scoreset specific, so we need additional 
> >>> +  # subroutines to handle those
> >>> +  if (defined &{'Mail::SpamAssassin::PerMsgStatus::'.$methodname}
> >> Prettier (IMHO):
> >>   if (Mail::SpamAssassin::PerMsgStatus->can($methodname)
> > Disappointingly, that's a defined test for a reason.  can() and defined()
> > don't always produce the same output!  That's why there's this double-test 
> > at
> > line 2901:
> 
> Yes, I figured it when I saw that; just forgot to delete the comment
> about it.
> 
> >>> +        && !$doing_user_rules)
> >>> +  {
> >>> +    no strict "refs";
> >>> +    
> >>> &{'Mail::SpamAssassin::PerMsgStatus::'.$methodname}($self,@extraevalargs);
> >>> +    use strict "refs";
> >> No need for 'no strict':
> >>   my $method = 'Mail::SpamAssassin::PerMsgStatus::' . $methodname;
> >>   $self->$method(@extraevalargs);
> > Sorry -- I'd need to see more platform checks to ensure that really *is* a
> > safe change now; it was added years ago by Matt for a reason, as I recall.
> 
> This syntax seems perfectly safe for me.  Maybe a ,,benchmark reason'':
> 
>                  Rate    oostyle stricthack
>   oostyle    277557/s         --       -21%
>   stricthack 349650/s        26%         --
> 
> How many times is it called for each message?  Do we get to process one
> more per year? ;-)

Doesn't this mean that the "strict" thing is faster? ;)

> [...]
> >>> +  package Mail::SpamAssassin::PerMsgStatus;
> [...]
> >> sub Mail::SpamAssassin::PerMsgStatus::$methodname {
> > Not equivalent; the latter does not have access to package-global
> > vars in Mail::SpamAssassin::PerMsgStatus scope without the "package"
> > line.  see:
> 
> Ah, I forgot about these.

--j.

Reply via email to