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

Reply via email to