In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/de06ff5a50f29eaee3e72394fa1c2417689cac47?hp=dc6369efc01b79eb657ea176c81cab927b54a2d1>
- Log ----------------------------------------------------------------- commit de06ff5a50f29eaee3e72394fa1c2417689cac47 Author: Eric Herman <e...@freesa.org> Date: Fri Nov 28 12:08:46 2014 +0100 Speed up assigning an IV to a previously cleared SV This change simply avoids calling sv_upgrade (which will do a ton of work to determine source and destination types) in a hot code path where at that very location, we've already just done all the same leg work to figure out source and destination types of the SV type conversion. In this particularly common and simple variant (SVt_NULL to SVt_IV), it's easy to do much better than sv_upgrade. Micro-benchmark used to validate this: $ dumbbench -i50 --pin-frequency -- \ ./perl -Ilib -e 'for my $x (1..1000){my @a = (1..2000);}' Before: Rounded run time per iteration: 2.4311e-01 +/- 1.4e-04 (0.1%) After: Rounded run time per iteration: 1.99354e-01 +/- 5.5e-05 (0.0%) That's 18% faster. While the micro-benchmark is very heavy on exercising this code path, it's a common code path. This is expected to have some real-world impact. There are likely more, similar optimizations that could have similar impact. NB: A similar change to newSViv also speeds up newSViv significantly, but newSViv is hardly used in the core. On the other hand, XS modules exercise it a lot. The Sereal decoder would be significantly, positively affected by doing a similar change there. ----------------------------------------------------------------------- Summary of changes: sv.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sv.c b/sv.c index bf6d11c..4a2850e 100644 --- a/sv.c +++ b/sv.c @@ -4307,7 +4307,13 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, SV* sstr, const I32 flags) if (SvIOK(sstr)) { switch (dtype) { case SVt_NULL: - sv_upgrade(dstr, SVt_IV); + /* For performance, we inline promoting to type SVt_IV. */ + /* We're starting from SVt_NULL, so provided that's + * actual 0, we don't have to unset any SV type flags + * to promote to SVt_IV. */ + assert(SVt_NULL == 0); + SET_SVANY_FOR_BODYLESS_IV(dstr); + SvFLAGS(dstr) |= SVt_IV; break; case SVt_NV: case SVt_PV: -- Perl5 Master Repository