diff options
author | Karl Williamson <khw@cpan.org> | 2020-01-10 11:45:39 -0700 |
---|---|---|
committer | Karl Williamson <khw@cpan.org> | 2020-01-13 20:58:56 -0700 |
commit | c969ff22d59d2aa1fa495b790f009037dc500787 (patch) | |
tree | 9dff45a770839d057665f4ef17facd4000bdf0a1 /embed.h | |
parent | 4b24f70353412ec749279fbcdb75b84ffd574c1c (diff) | |
download | perl-c969ff22d59d2aa1fa495b790f009037dc500787.tar.gz |
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
Diffstat (limited to 'embed.h')
-rw-r--r-- | embed.h | 5 |
1 files changed, 4 insertions, 1 deletions
@@ -188,7 +188,7 @@ #define getcwd_sv(a) Perl_getcwd_sv(aTHX_ a) #define gp_free(a) Perl_gp_free(aTHX_ a) #define gp_ref(a) Perl_gp_ref(aTHX_ a) -#define grok_bin_oct_hex(a,b,c,d,e) Perl_grok_bin_oct_hex(aTHX_ a,b,c,d,e) +#define grok_bin_oct_hex(a,b,c,d,e,f,g) Perl_grok_bin_oct_hex(aTHX_ a,b,c,d,e,f,g) #define grok_infnan(a,b) Perl_grok_infnan(aTHX_ a,b) #define grok_number(a,b,c) Perl_grok_number(aTHX_ a,b,c) #define grok_number_flags(a,b,c,d) Perl_grok_number_flags(aTHX_ a,b,c,d) @@ -1688,6 +1688,9 @@ #define mro_gather_and_rename(a,b,c,d,e) S_mro_gather_and_rename(aTHX_ a,b,c,d,e) #define mro_get_linear_isa_dfs(a,b) S_mro_get_linear_isa_dfs(aTHX_ a,b) # endif +# if defined(PERL_IN_NUMERIC_C) +#define output_non_portable(a) S_output_non_portable(aTHX_ a) +# endif # if defined(PERL_IN_OP_C) #define apply_attrs(a,b,c) S_apply_attrs(aTHX_ a,b,c) #define apply_attrs_my(a,b,c,d) S_apply_attrs_my(aTHX_ a,b,c,d) |