develooper Front page | perl.perl5.porters | Postings from February 2014

a couple of optimisation branches

Thread Next
From:
Dave Mitchell
Date:
February 23, 2014 10:02
Subject:
a couple of optimisation branches
Message ID:
20140223100217.GL1615@iabyn.com
I've just pushed a couple of minor optimisation branches out for smoking
and comment:

    smoke-me/davem/aelemfast
    smoke-me/davem/overload

Unless there's any adverse feedback, I'll merge them both soonish.

The first is a single self-explanatory commit. The only issue with it is
that it converts the 8-bit index stored in op_private for aelemfast from
being interpreted as unsigned to signed, which could require B:: or
Devel:: type modules to need fixups before 5.20 is released.

    commit 4c025f36447f8a4bd1eb21995f13399db0a4baed
    Author:     David Mitchell <davem@iabyn.com>
    AuthorDate: Sun Feb 23 00:53:17 2014 +0000
    Commit:     David Mitchell <davem@iabyn.com>
    CommitDate: Sun Feb 23 00:53:17 2014 +0000

    make OP_AELEMFAST work with negative indices
    
    Use aelemfast for literal index array access where the index is in the
    range -128..127, rather than 0..255.
    
    You'd expect something like $a[-1] or $a[-2] to be a lot more common than
    $a[100] say. In fact a quick CPAN grep shows 66 distributions
    matching /\$\w+\[\d{3,}\]/, but "at least" 1000 matching /\$\w+\[\-\d\]/.
    And most of the former appear to be table initialisations.

This contrived microbenchmark shows a reduction in time from 14.5s to 11.3s:

    my @a = (1..10);
    my $x;
    $x = $a[-1]+$a[-2] + $a[-3] for 1..100_000_000;



The second branch is a small series of commits intended to fix a
performance issue with overloading. The commit below describes the actual
issue and fix; but a couple of commits preceding that lay the groundwork
by adding a new flags field to the HvAUX() structure. HvAUX() is an
optional auxiliary structure allocated at the end of HvARRAY() to allow
space for the extra fields needed when a hash is being used as a stash, or
is being iterated over: fields that would just be wasted space for a
simple hash object.

Adding this new flags field for just the stash/iterated hash case also frees
up one general SV flag for future use by PVHV's: SVf_UTF8 (which I'd like
to informally reserve).


    commit 534692cd6a815de9c3e7e6b7fc1203aca639e8d9
    Author:     David Mitchell <davem@iabyn.com>
    AuthorDate: Sat Feb 15 22:47:16 2014 +0000
    Commit:     David Mitchell <davem@iabyn.com>
    CommitDate: Sat Feb 22 21:48:27 2014 +0000

    speed up (non)overloaded derefs
    
    Consider a class that has some minimal overloading added - e.g. to give
    pretty stringification of objects - but which *doesn't* overload
    dereference methods such as '@[]'. '%[]' etc.
    
    In this case, simple dereferencing, such as $obj->[0] or  $obj->{foo}
    becomes much slower than if the object was blessed into a non-overloaded
    class.
    
    This is because every time a dereferencing is performed in pp_rv2av for
    example, the "normal" code path has to go through the full checking of:
    
      * is the stash into which the referent is blessed overloaded? If so,
      * retrieve the overload magic from the stash;
      * check whether the overload method cache has been invalidated and if so
        rebuild it;
      * check whether we are in the scope of 'no overloading', and if so
        is the current method disabled in this scope?
      * Is there a '@{}' or whatever (or 'nomethod') method in the cache?
        If not, then process the ref as normal.
    
    That's a lot of extra overhead to decide that an overloaded method doesn't
    in fact need to be called.
    
    This commit adds a new flag to the newish xhv_aux_flags field,
    HvAUXf_NO_DEREF, which signals that the overloading of this stash
    contains no deref (nor 'nomethod') overloaded methods. Thus a quick check
    for this flag in the common case allows us to short-circuit all the above
    checks except the first one.
    
    Before this commit, a simple $obj->[0] was about 40-50% slower if the
    class it was blessed into was overloaded (but didn't have deref methods);
    after the commit, the slowdown is 0-10%. (These timings are very
    approximate, given the vagaries of nano benchmarks.)


-- 
A major Starfleet emergency breaks out near the Enterprise, but
fortunately some other ships in the area are able to deal with it to
everyone's satisfaction.
    -- Things That Never Happen in "Star Trek" #13

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About