summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Leach <richardleach@users.noreply.github.com>2022-07-14 11:46:33 +0000
committerPaul Evans <leonerd@leonerd.org.uk>2022-07-20 14:08:25 +0100
commit80c024ac46cfd7ea9195a681104a2c19cc18dcbf (patch)
tree82d4274f72d1b84e9f20d329a398987b66ea85ef
parent3b6b0454f77464cedcad7102764c6788a4f14ba8 (diff)
downloadperl-80c024ac46cfd7ea9195a681104a2c19cc18dcbf.tar.gz
newAVav - av_push_simple for faster ret array assignment
-rw-r--r--av.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/av.c b/av.c
index 985e0be4d7..a990e13c55 100644
--- a/av.c
+++ b/av.c
@@ -466,15 +466,11 @@ Perl_newAVav(pTHX_ AV *oav)
{
PERL_ARGS_ASSERT_NEWAVAV;
- U32 count = av_count(oav);
+ Size_t count = av_count(oav);
if(UNLIKELY(!oav) || count == 0)
return newAV();
- if(LIKELY(!SvRMAGICAL(oav))) {
- return av_make(av_count(oav), AvARRAY(oav));
- }
-
AV *ret = newAV_alloc_x(count);
/* avoid ret being leaked if croak when calling magic below */
@@ -482,9 +478,17 @@ Perl_newAVav(pTHX_ AV *oav)
PL_tmps_stack[++PL_tmps_ix] = (SV *)ret;
SSize_t ret_at_tmps_ix = PL_tmps_ix;
- for(U32 i = 0; i < count; i++) {
- SV **svp = av_fetch(oav, i, 0);
- av_push(ret, svp ? newSVsv(*svp) : &PL_sv_undef);
+ Size_t i;
+ if(LIKELY(!SvRMAGICAL(oav) && AvREAL(oav) && (SvTYPE(oav) == SVt_PVAV))) {
+ for(i = 0; i < count; i++) {
+ SV **svp = av_fetch_simple(oav, i, 0);
+ av_push_simple(ret, svp ? newSVsv(*svp) : &PL_sv_undef);
+ }
+ } else {
+ for(i = 0; i < count; i++) {
+ SV **svp = av_fetch(oav, i, 0);
+ av_push_simple(ret, svp ? newSVsv(*svp) : &PL_sv_undef);
+ }
}
/* disarm leak guard */