Speed up assigning an IV to a previously cleared SV
authorEric Herman <eric@freesa.org>
Fri, 28 Nov 2014 11:08:46 +0000 (12:08 +0100)
committerSteffen Mueller <smueller@cpan.org>
Fri, 28 Nov 2014 11:08:46 +0000 (12:08 +0100)
commitde06ff5a50f29eaee3e72394fa1c2417689cac47
tree711cfab543c03a59f75a1be01264658ad542d2d8
parentdc6369efc01b79eb657ea176c81cab927b54a2d1
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.
sv.c