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" #13Thread Next