Speed up newSViv()
authorEric Herman <eric@freesa.org>
Fri, 28 Nov 2014 14:08:04 +0000 (15:08 +0100)
committerSteffen Mueller <smueller@cpan.org>
Fri, 28 Nov 2014 14:45:47 +0000 (15:45 +0100)
commitbd30fe8921c88e4677c2279b442a56a11ae037b4
treef5a7044e46aecfb36e954c98e1e5aef293c11928
parentde06ff5a50f29eaee3e72394fa1c2417689cac47
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.
sv.c