Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Re-imagine List.from-slurpy-flat
It struck me that if a sub has a slurpy array, and the values specified
are all simple scalars without any additional Slippy/Iterable functionality,
that the $!future created (which is the $!todo of the List/Array to be)
is in fact already what $!reified will be in the end.  So in that case
we can just put the $!future into $!reified, and we're done:

  sub a(*@A) { }; a(1,2,3,4);

sees an improvement of 30% compared to a(), and 3 allocations less.

This spectests clean.  But this is the area of dragons, so there may
be some ecosystem fallout.  In that case, just revert this commit.
  • Loading branch information
lizmat committed Jul 10, 2016
1 parent a02fdbe commit de5d9e7
Showing 1 changed file with 49 additions and 30 deletions.
79 changes: 49 additions & 30 deletions src/core/List.pm
Expand Up @@ -341,48 +341,67 @@ my class List does Iterable does Positional { # declared in BOOTSTRAP
}

method from-slurpy-flat(|) {
my \result := nqp::create(self);
my Mu \vm-tuple = nqp::captureposarg(nqp::usecapture(), 1);
my int $elems = nqp::elems(vm-tuple);
my int $i = -1;
my $consider;

nqp::if(
nqp::isgt_i($elems,0),
(my int $elems = nqp::elems(
(my Mu $vm-tuple := nqp::captureposarg(nqp::usecapture,1))
)),
nqp::stmts(
nqp::bindattr(result,List,'$!reified',
my \buffer := nqp::create(IterationBuffer)),
nqp::bindattr(result,List,'$!todo',
my \todo := nqp::create(List::Reifier)),
nqp::bindattr(todo,List::Reifier,'$!reified',
buffer),
nqp::bindattr(todo,List::Reifier,'$!reification-target',
result.reification-target),
nqp::bindattr(todo,List::Reifier,'$!future',
my \future := nqp::setelems(nqp::create(IterationBuffer),$elems)),
(my $future := nqp::setelems(nqp::create(IterationBuffer),$elems)),
(my int $i = -1),
(my int $b = 0),
nqp::while(
nqp::islt_i($i = nqp::add_i($i,1),$elems),
nqp::stmts(
($consider := nqp::atpos(vm-tuple,$i)),
nqp::if(
nqp::iscont(my $consider := nqp::atpos($vm-tuple,$i)),
nqp::bindpos($future,$i,$consider),
nqp::if(
nqp::iscont($consider),
nqp::bindpos(future,$i,$consider),
(nqp::istype($consider,Iterable) && $consider.DEFINITE),
nqp::if(
(nqp::istype($consider, Iterable) && $consider.DEFINITE),
nqp::if(
nqp::istype($consider, PositionalBindFailover),
nqp::bindpos(future,$i,$consider.cache.flat.Slip),
nqp::bindpos(future,$i,$consider.flat.Slip)
),
nqp::bindpos(future,$i,$consider)
nqp::istype($consider,PositionalBindFailover),
nqp::bindpos($future,$i,$consider.cache.flat.Slip),
nqp::bindpos($future,$i,$consider.flat.Slip)
),
nqp::stmts(
nqp::bindpos($future,$i,$consider),
($b = nqp::add_i($b,1))
)
)
)
),
nqp::if(
nqp::iseq_i($b,$elems),

# we already reified everything
nqp::p6bindattrinvres(nqp::create(self),List,'$!reified',$future),

# need full fledged List with a $todo
nqp::stmts(
(my $result :=
nqp::p6bindattrinvres(nqp::create(self),List,'$!reified',
(my $buffer := nqp::create(IterationBuffer))
)
),
nqp::bindattr($result,List,'$!todo',
(my $todo := nqp::create(List::Reifier))
),
nqp::bindattr($todo,List::Reifier,'$!reified',
$buffer
),
nqp::bindattr($todo,List::Reifier,'$!reification-target',
$result.reification-target
),
nqp::bindattr($todo,List::Reifier,'$!future',
$future
),
$result
)
)
)
);
),

result
# no args, an empty list suffices
nqp::create(self)
)
}

method new(**@things) {
Expand Down

0 comments on commit de5d9e7

Please sign in to comment.