develooper Front page | perl.perl5.porters | Postings from October 2012

Re: COW status [perl #114820]

Thread Next
Father Chrysostomos via RT
October 23, 2012 13:02
Re: COW status [perl #114820]
Message ID:
On Tue Oct 16 10:14:42 2012, sprout wrote:
> On Mon Oct 08 08:40:33 2012, sprout wrote:
> > On Mon Oct 08 00:37:16 2012, sprout wrote:
> > > You can play with it if you want.  It’s on the sprout/ookow branch
> > > (SvOOK-style COW [except it does not involve SvOOK any more]).
> > 
> > I forgot to mention it requires -Accflags=-DPERL_NEW_COPY_ON_WRITE.
> And now I have all core tests passing, except Peek.t, which will need
> tweaking when I have finished.
> I still need to do some benchmarks to find a threshold where
> copy-on-write speeds things up (and then only do COW above that
> threshold).  We may need two thresholds depending on whether the
> destination string has a buffer already, and whether that buffer is big
> enough.  (Copying may be faster than freeing a buffer.)

You can now see this on the sprout/ookow2 branch.  It still requires

There are two #defines, SV_COW_THRESHOLD and SV_COWBUF_THRESHOLD.  These
are minimum string lengths where COW kicks in.  The latter is used if
the destination string already has a buffer large enough to hold the string.

For benchmarking I compiled without -DDEBUGGING.  Earlier I had used it,
but it skewed the results because of extra PL_debug & DEBUG_C_FLAG
checks in the COW-handling code.

I tried those silly benchmarks with repeated variable assignment in a
loop, and found that sv_force_normal_flags is the real bottleneck when
it comes to copy-on-write.  For these simple loops, the COW overhead
exceeds the cost of copying up to 209 bytes.  Above that, COW is faster.
 If the destination string is already large enough, then copying is so
fast that it beats the pants of COW up to 2131 bytes.

When I tried those numbers (209/2131) with mktables, it made absolutely
no difference to the speed, but 0/0 (always COW) showed a slight
speed-up.  So I did repeated tests with different numbers and found
0/500 to be ideal.

I then tried David Wheeler’s Test.Simple JavaScript library with
WWW::Scripter.  Its test suite is written in JavaScript and runs in a
browser (like WWW::Scripter :-).  The optimum setting seemed to be
0/1250, which is just as fast as 0/500 for mktables.  So that’s the
setting I currently have on my branch.

I set up those #defines with #ifndef conditions so that
platform-specific hints can override them.  I’m sure the ideal settings
will be different for Windows, for instance.

For anyone who wants to try Test.Simple with blead (I think it makes a
good benchmark):

Get JS::Test::Simple off CPAN and then move the tests/ folder somewhere
convenient (I used /ts/).

Install Lexical::Var into your blead installation with the patch from

Install WWW::Scripter::Plugin::Ajax.

Then run this ‘one’-liner, with the right file: URL:

bleadperl -MTime::HiRes=sleep -e '++$INC{"JE/"};use
WWW::Scripter; agent_alias{$w=new WWW::Scripter}"Mac Safari";
$w->use_plugin(Ajax); $w->get("file:///ts/index.html ");
$w->wait_for_timers;  print $w->content(format=>text)'

The %INC fiddling is a necessary hack.  It basically has to do with
WWW::Scripter::Plugin::JavaScript’s attempts to handle circular
references conflicting with Test.Simple’s expectations.  Pretending to
load JE::Destroyer disables that circularity handling.

> I also need to allocate that extra byte for strings above the COW
> threshold, to store the buffer’s reference count.

Not done yet, but that is next on my list.

> And then I need to see whether eliminating swipe makes any speed

Yes.  It makes things slower.

(And, smueller, did you see my message about smoking sprout/ookow?  If
you have not started, could you use sprout/ookow2 instead?  Thank you.)


Father Chrysostomos

via perlbug:  queue: perl5 status: open

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About