In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/bd30fe8921c88e4677c2279b442a56a11ae037b4?hp=de06ff5a50f29eaee3e72394fa1c2417689cac47>
- Log ----------------------------------------------------------------- commit bd30fe8921c88e4677c2279b442a56a11ae037b4 Author: Eric Herman <e...@freesa.org> Date: Fri Nov 28 15:08:04 2014 +0100 Speed up newSViv() newSViv() is not used a whole lot by the core. But it is frequently used in XS modules. In a nutshell, it allocates a new EMPTY SV just to call sv_setiv which calls sv_upgrade which in turn spends inordinate amounts of time looking at the properties of the SV to make it an SVt_IV. But the properties of that SV are always the same: a clean slate! Therefore, inlining the very simple bits of sv_setiv that are actually necessary gives a very tangible speed-up. It's not very easy to benchmark with with a language-level one-liner because newSViv() isn't too common in the core. Thus follow XS micro-benchmarks: Benchmark 1: Virtually no-op XS function. SV * echo_integer(int in) CODE: RETVAL = newSViv(in); OUTPUT: RETVAL $ dumbbench -i50 --pin-frequency -- ./perl -Ilib \ -MXS::APItest -e 'XS::APItest::echo_integer($_) for 1..1000000' Before: 3.2782e-01 seconds After: 3.0530e-01 seconds A small change, but considering the massive overhead of a function call, quite surprisingly noticeable. Benchmark 2: XS function that constructs multiple integer values. SV * echo_integer_array(int in) PREINIT: int i; AV *av; CODE: av = newAV(); RETVAL = newRV_noinc((SV *)av); av_extend(av, in-1); for (i = 0; i < in; ++i) av_store(av, i, newSViv(i)); OUTPUT: RETVAL $ dumbbench -i50 --pin-frequency -- ./perl -Ilib \ -MXS::APItest -e 'XS::APItest::echo_integer_array(100) for 1..10000' Before: 1.18363e-01 seconds After: 0.92050e-01 seconds While in the grand scheme of things, this might seem like a very small optimization, there are many XS modules that actually generate a lot of integer values, de-serializers being good examples. ----------------------------------------------------------------------- Summary of changes: sv.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sv.c b/sv.c index 4a2850e..40b614e 100644 --- a/sv.c +++ b/sv.c @@ -9359,7 +9359,22 @@ Perl_newSViv(pTHX_ const IV i) SV *sv; new_SV(sv); - sv_setiv(sv,i); + + /* Inlining ONLY the small relevant subset of sv_setiv here + * for performance. Makes a significant difference. */ + + /* We're starting from SVt_FIRST, so provided that's + * actual 0, we don't have to unset any SV type flags + * to promote to SVt_IV. */ + assert(SVt_FIRST == 0); + + SET_SVANY_FOR_BODYLESS_IV(sv); + SvFLAGS(sv) |= SVt_IV; + (void)SvIOK_on(sv); + + SvIV_set(sv, i); + SvTAINT(sv); + return sv; } -- Perl5 Master Repository