On 20 August 2010 21:43, Jan Dubois <jand@activestate.com> wrote:
> On Fri, 20 Aug 2010, demerphq wrote:
>> On 14 August 2010 02:39, Jan Dubois <jand@activestate.com> wrote:
>> > Things that could benefit from further discussion are:
>> >
>> > a) the algorithm in sv_grow() for expanding SVs with SvOOK
>> >
>> > if (newlen > SvLEN(sv))
>> > newlen += 10 * (newlen - SvCUR(sv)); /* avoid copy each time */
>> >
>> > This doesn't make much sense, and is catastrophic when
>> > you append a very long string to a short one. I have not looked
>> > into the heritage of this algorithm yet.
>>
>> I suspect this was Nicholas'es hack to reduce the number of times
>> realloc is called when appending single characters to a buffer over
>> and over.
>
> This code is only executed when the SvOOK bit is set (which means that
> some bytes at the beginning of the allocated block have been chopped
> off). Are you sure that applies to the Data::Dumper::XS case (yes, I'm
> too lazy^H^H^H^Hbusy to hunt through Dumper.xs right now).
>
>> One thing I have a bit of hesitancy about is it seems the benchmarks
>> here, (emphasis on seems i havent looked very closely unfortunately)
>> is that they /look/ like they involve concatenating large strings
>> together. These types of benchmarks will "blow" the merge block
>> algorithm used in some reallocs (depending on memory pressures, etc on
>> the system at the time), the original thought was to address the
>> performance of code like this:
>>
>> my $str="";
>> $str.="x" for 1...100000;
>
> No the benchmarks in this thread are all about concatenating small strings
> to large buffers.
>
> Just to reiterate it once more: the "new" patch will not kick in *at all*
> if the required new size is more than (25% + 10 bytes) larger than the
> old size. It only helps repeated appends of smallish increments.
>
>> If we dont overallocate AND we are using a malloc/realloc that doesnt
>> do block merges (like Windows worked when I last used Windows) you end
>> up getting quadratic performance as each concatenation ends up being a
>> realloc call, which in turn ends up doing a memcopy(). Which means one
>> ends up doing a ridiculously large amount of data copying.
>
> Yes, that is exactly the problem this change is supposed to "solve".
>
>> If i recall correctly Nicholas made a comment along the lines of "best
>> performance gain for least effort" of any patch he had ever written.
>
> Could you hunt down the original discussion (and commit id) of Nicholas
> patch? I don't quite understand how we can still get such huge improvements
> if this is supposedly already fixed.
>
> The one patch from Nicholas that I know about is that under -Dusemymalloc
> he queries the size of the new block and assigns that number to SvLEN
> instead of the requested size. That prevents additional calls to sv_grow()
> when the block wouldn't have to move because realloc() already overallocated.
>
> But that patch does nothing for other allocators.
Im pretty sure its this one:
$ git log -1 1936d2a74fbc35dd0d686
commit 1936d2a74fbc35dd0d6862386c9988d92bb8e6e0
Author: Nicholas Clark <nick@ccl4.org>
Date: Wed Jun 1 20:46:02 2005 +0000
Round up all string length requests to malloc()/realloc() to the next
multiple of 4/8 bytes [sizeof(size_t)] on the assumption that malloc()
internally will quantise, and so we're going to use space that
otherwise would be wasted. Hopefully this will save realloc()ing.
p4raw-id: //depot/perl@24665
But i cant find the mail about it. I do recall some of the discussion
was on IRC, but I also remember a mail. Unfortunately (for some not
very unfortunate definition of unfortunate :-) Nicholas improves
performance all the time, so the keywords I keep looking for in my
mailbox give a rather large number of hits and ive yet to find the
right one. Perhaps he remembers?
cheers
Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"
Thread Previous
|
Thread Next