diff options
author | David Mitchell <davem@iabyn.com> | 2014-02-15 22:47:16 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2014-02-28 13:42:49 +0000 |
commit | 3d147ac29d12abdb2ed2e2bc6a5c0963319ea7b1 (patch) | |
tree | d08521be24eee6c2a595a525f1ac200637d53279 /hv.h | |
parent | 39a65960f578e84da484cf5206f04b0c365450ff (diff) | |
download | perl-3d147ac29d12abdb2ed2e2bc6a5c0963319ea7b1.tar.gz |
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.)
Diffstat (limited to 'hv.h')
-rw-r--r-- | hv.h | 1 |
1 files changed, 1 insertions, 0 deletions
@@ -123,6 +123,7 @@ struct xpvhv_aux { }; #define HvAUXf_SCAN_STASH 0x1 /* stash is being scanned by gv_check */ +#define HvAUXf_NO_DEREF 0x2 /* @{}, %{} etc (and nomethod) not present */ /* hash structure: */ /* This structure must match the beginning of struct xpvmg in sv.h. */ |