-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Perl_do_print: stringify an SVt_IV IV/UV more efficiently #22927
base: blead
Are you sure you want to change the base?
Conversation
This allows other parts of core to do integer stringification using the same, fast function.
`Perl_do_print`'s pre-existing method for stringification of an IV within an SVt_IV involves creating a temporary SVt_PV, using `sv_vcatpvfn_flags` to do the stringification, then freeing the SVt_PV once the buffer has been written out. This is considerably slower than using `S_uiv_2buf`, the helper function used by `sv_2pv_flags`. So this commit modifies `Perl_do_print` to use `sv_2pv_flags`.
static const union { | ||
char arr[200]; | ||
U16 dummy; | ||
} int2str_table = {{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this symbol be visible in external (C/XS) code? Because at the moment it is an unprefixed identifier (no Perl_
or anything) in the global namespace.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I'm not sure how best to handle it. Happy to take advice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guarding it inside a #if defined(PERL_CORE) || defined (PERL_EXT)
?
else | ||
PerlIO_printf(fp, "%" IVdf, (IV)SvIVX(sv)); | ||
return !PerlIO_error(fp); | ||
bool happy = TRUE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is happy
declared so far away from its first use?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mirroring the else
branch of Perl_do_print
. I kept it it the same for consistency. Happy to change both instances in a follow-up commit.
if (len && (PerlIO_write(fp,ptr,len) == 0)) | ||
happy = FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be
bool happy = !(len && PerlIO_write(fp, ptr, len) == 0);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied from the else
branch of Perl_do_print
. I kept it it the same for consistency. Happy to change both instances in a follow-up commit.
|
||
if (len && (PerlIO_write(fp,ptr,len) == 0)) | ||
happy = FALSE; | ||
return happy ? !PerlIO_error(fp) : FALSE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be
return happy && !PerlIO_error(fp);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was copied from the else
branch of Perl_do_print
. I kept it it the same for consistency. Happy to change both instances in a follow-up commit.
https://stackoverflow.com/questions/79244888 points out that
pp_print
is really slow at stringifying integers. It's bizarrely much faster to add
additional operations to do the stringification first.
Here are some sample timings:
Note from the last timing that stringification in
pp_print
is notalways slow, only when the IV is stored in a SVt_IV. This traces back
to
Perl_do_print
which has a special path for just this case:(There are no code comments to say why it does this. Perhaps deliberately
preserving the type for some reason?)
PerlIO_printf
callsPerlIO_vprintf
, which callsPerl_vnewSVpvf
, whichcreates a new (effectively) temporary SV, then sends that to
Perl_sv_vcatpvfn_flags
for stringification and storage of the IV.PerlIO_vprintf
then writes out the buffer from the temp SV and frees it.All the other routes essentially call
SvPV_const
on$i
or aPADTMP
.This invokes
sv_2pv_flags
and its helper,S_uiv_2buf
, does the work.No temporary SVs are created and freed in such cases.
This PR changes
Perl_do_print
to also use a small buffer andS_uiv_2buf
to do the stringification more efficiently, whilst stillavoiding a type upgrade, Re-measuring after this PR: