This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
speed up AV and HV clearing/undeffing
authorDavid Mitchell <davem@iabyn.com>
Wed, 26 Oct 2016 14:59:01 +0000 (15:59 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 26 Oct 2016 15:21:52 +0000 (16:21 +0100)
commitbe98855787c93fb16a7d4974601d4c8cf91ab8cb
tree6366dab91b8d6f33671909b9a7057bc5b363beb7
parente379d8b6255668c15f5454b32dcbfd8b1f462a9f
speed up AV and HV clearing/undeffing

av_clear(), av_undef(), hv_clear(), hv_undef() and av_make()
all have similar guards along the lines of:

    ENTER;
    SAVEFREESV(SvREFCNT_inc_simple_NN(av));
    ... do stuff ...;
    LEAVE;

to stop the AV or HV leaking or being prematurely freed while processing
its elements (e.g. FETCH() or DESTROY() might do something to it).

Introducing an extra scope and calling leave_scope() is expensive.
Instead, use a trick I introduced in my recent pp_assign() recoding:
add the AV/HV to the temps stack, then at the end of the function,
just PL_tmpx_ix-- if nothing else has been pushed on the tmps stack in the
meantime, or replace the tmps stack slot with &PL_sv_undef otherwise
(which doesn't care how many times its ref count gets decremented).

This is efficient, and doesn't artificially extend the life of the SV
like sv_2mortal() would.

This commit makes this code around 5% faster:

    my @a;
    for my $i (1..3_000_000) {
        @a = (1,2,3);
        @a = ();
    }

and this code around 3% faster:

    my %h;
    for my $i (1..3_000_000) {
        %h = qw(a 1 b 2);
        %h = ();
    }
av.c
hv.c