You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
add sv_refhek, sv_reftypehek functions for better ref() performance
-ref() PP keyword has extremely high usage. Greping my blead repo shows:
Searched "ref(" 4347 hits in 605 files of 5879 searched
-High level PP keyword ref(), aka C function Perl_pp_ref(), uses slow,
inefficient, badly designed, backend public XS/C API called functions
called Perl_sv_ref()/Perl_sv_reftype().
-This commit fixes all design problems with Perl_sv_ref()/Perl_sv_reftype(),
and will speed up the very high usage PP keyword ref(), along with a
very similar but very new and very little used PP keyword called
"use builtin qw( reftype );" which is near identical to Perl_pp_ref().
-a crude benchmark, with the array ref in $aref holding
43000 SV*s, split 1/3rd SV* IOK, 1/3rd RV* to SV* IOK,
and 1/3rd RV* to CV*, showed a %6 speed increase for this code
sub benchme {
foreach my $el (@{$aref}) { $cnt++ if ref($el) eq 'SCALAR';}
}
-The all UPPERCASE strings keyword ref() returns are part of the Perl 5
BNF grammer. Changing their spelling or lowercasing them is not for
debate, or i18n-ing them dynamically realtime against glibc.so's current
"OS global locale" with inotify()/kqueue() in the runloop to monitor a
text file /etc or /var so this race condition works as designed in a
unit test will never happen:
$perl -E "dire('hello')"
Routine indéfinie &cœur::dire aufgerufen bei -e Zeile 1
-sv_reftype() and sv_ref() have very badly designed prototypes, and the
first time a new Perl in C dev reads their source code, they will think
these 2 will cause infinite C stack recursion and a SEGV. Probably most
automated C code analytic tools maybe will complain these 2 functions do
infinite recursion.
-The 2 functions don't return a string length, forcing all callers to
execute a libc strlen() call on a string, that could be 8 bytes, or 80 MB.
-All null term-ed strings that they return, are already sitting in virtual
address space. Either const HW RO, or RCed HEK*s from the PL_strtab pool,
that were found inside something similar to a
GV*/HV*/HE*/CV*/AV*/GP*/OP*/SV* in a OP*(no threads)
.
-COW 255 buffers from Newx() under 9 chars can't COW currently by policy.
CODE is 4, SCALAR is 6. HASH is 4. ARRAY is 5. But very short SV HEK* COWs
will COW propagate without problems. ref() is also used to retrieve
"Local::My::Class" strings, which have an extremely high chance to wind
up getting passed to hv_common() through some high level PP keyword like
bless or @isa, and hv_common() extracts precalculated U32 hash values
from SV* with HEK* buffers, speeding up hv_common(). So SV* POKs with
COW 255 and COW SVs_STATIC buffers are bad choices compared to using SV*
POK HEK* buffers for a new faster version of sv_reftype()/sv_ref().
-PP code "if(ref($self) eq 'HASH') {}" should never involve all 3-5 calls
Newx()/Realloc()/strlen()/memcpy()/Safefree(), on each execution of the
line.
To improve the src code dev-friendlyness of the prototypes of, and speed
inside of, and the speed of in all libperl callers of
Perl_sv_ref()/Perl_sv_reftype(). Make HEK* variants of them. Initially
the HEK* variants are private to libperl. Maybe after 1-3 years into the
future, they can be made official public C API for CPAN XS authors.
These 2 new functions are undocumented/private API until further notice.
Using SV* holding RC-ed HEK* SvPVX() buffers removes all these libc
C lang logical and/or Asm machine code steps from during execution of
PP keyword ref(). The pre-allocated PAD TARG SV* just keeps getting
a RC-- on the old HEK* inside SvPVX(), and a RC++ on the new HEK* written
to SvPVX() of the PAD TARG SV*. Touching only 6 void*s/size_t adresses
total, each one a single read/write CPU instruction pair.
SvPVX, SvCUR, SvLEN, old_hek.shared_he.shared_he_he.he_valu.hent_refcount,
new_hek.shared_he.shared_he_he.he_valu.hent_refcount,
new_hek.shared_he.shared_he_hek.hek_len. This brings PP KW ref() closer
to C++ style RTTI that just compares const read-only vtable pointers.
Some design and optimization problems with the old and new
pp_ref()/pp_reftype()/sv_ref()/sv_reftype()/sv_refhek()/sv_reftypehek()
calls are intentionally not being fixed in this commit to keep this
commit small. Check the associated PR of the commit for details.
0 commit comments