summaryrefslogtreecommitdiff
path: root/hv.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-02-15 22:47:16 +0000
committerDavid Mitchell <davem@iabyn.com>2014-02-28 13:42:49 +0000
commit3d147ac29d12abdb2ed2e2bc6a5c0963319ea7b1 (patch)
treed08521be24eee6c2a595a525f1ac200637d53279 /hv.h
parent39a65960f578e84da484cf5206f04b0c365450ff (diff)
downloadperl-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.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/hv.h b/hv.h
index 5ad1459a2e..5b52f98460 100644
--- a/hv.h
+++ b/hv.h
@@ -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. */