This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Improve performance of grok_bin_oct_hex()
authorKarl Williamson <khw@cpan.org>
Fri, 10 Jan 2020 18:45:39 +0000 (11:45 -0700)
committerKarl Williamson <khw@cpan.org>
Tue, 14 Jan 2020 03:58:56 +0000 (20:58 -0700)
commitc969ff22d59d2aa1fa495b790f009037dc500787
tree9dff45a770839d057665f4ef17facd4000bdf0a1
parent4b24f70353412ec749279fbcdb75b84ffd574c1c
Improve performance of grok_bin_oct_hex()

This commit uses a variety of techniques for speeding this up.  It is
now faster than blead, and has less maintenance cost than before.

Most of the checks that the current character isn't NUL are unnecssary.
The logic works on that character, even if, for some reason, you can't
trust the input length.  A special test is added to not output the
illegal character message if that character is a NUL.  This is simply
for backcompat.

And a switch statement is used to unroll the loop for the leading digits
in the number.  This should handle most common cases.  Beyond these, and
one has to start worrying about overflow.  So this version has removed
that worrying from the common cases.

Extra conditionals are avoided for large numbers by extracting the
portability warning message code into a separate static function called
from two different places.  Simplifying this logic led me to see that if
it overflowed, it must be non-portable, so another conditional could be
removed.

Other conditionals were removed at the expense of adding parameters to
the function.  This function isn't public, but is called from the
grok_hex, et. al. macros.  grok_hex knows, for example, that it is
looking for an 'x' prefix and not a 'b'.  Previously the code had a
conditional to determine that.

Similarly in pp.c, we look for the prefix.  Having found it we can start
the parse after the prefix, and tell this function not to look for it.
Previously, this work was duplicated.

The previous changes had left this function slower than blead.  That is
in part due to the fact that the loop doesn't go through that many
iterations per function call, and the gcc compiler managed to optimize
away the conditionals in XDIGIT_VALUE in the call of it from the loop.
(The other call in this function did have the conditionals.)

Thanks to Sergey Aleynikov for his help on this
embed.fnc
embed.h
numeric.c
perl.h
pp.c
proto.h