Skip to content

Commit

Permalink
Simplify iterator selection for map
Browse files Browse the repository at this point in the history
This should allow for easier inlining and marginally faster calls
to .map.

- Add "has_phasers" methods to WhateverCode and ForeignCode
  So that we don't have to check what type of Callable we actually
  got.

- Remove IterateOneNotSlippingWithoutPhasers iterator
  Not sure what I was on when I created that iterator, nor when I
  did the control structure.  Basically, it doesn't add anything
  even remote sensible nowadays, so remove it.

- Simplify ForeignCode.count/arity
  They are *always* the same, the do not need to be derived from
  the signature of a sub that is always the same.
  • Loading branch information
lizmat committed Jun 19, 2021
1 parent cd01706 commit a8f144c
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 119 deletions.
126 changes: 10 additions & 116 deletions src/core.c/Any-iterable-methods.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -293,106 +293,6 @@ Consider using a block if any of these are necessary for your mapping code."
}
}

my class IterateOneNotSlippingWithoutPhasers does Iterator {
has &!block;
has $!source;
has $!label;

method new(&block,$source,\label) {
my $iter := nqp::create(self);
nqp::bindattr($iter, self, '&!block', &block);
nqp::bindattr($iter, self, '$!source', $source);
nqp::bindattr($iter, self, '$!label', nqp::decont(label));
$iter
}

method is-lazy() { $!source.is-lazy }

method pull-one() is raw {
if nqp::eqaddr((my $pulled := $!source.pull-one),IterationEnd) {
IterationEnd
}
else {
my $result;
my int $stopped;
nqp::stmts(
nqp::until(
$stopped,
nqp::stmts(
($stopped = 1),
nqp::handle(
($result := &!block($pulled)),
'LABELED', $!label,
'NEXT', nqp::if(
nqp::eqaddr(
($pulled := $!source.pull-one),
IterationEnd
),
($result := IterationEnd),
($stopped = 0)
),
'REDO', ($stopped = 0),
'LAST', ($result := IterationEnd)
),
),
:nohandler
),
$result
)
}
}

method push-all(\target --> IterationEnd) {
my $pulled;
my int $stopped;
nqp::until(
nqp::eqaddr(($pulled := $!source.pull-one),IterationEnd),
nqp::stmts(
($stopped = 0),
nqp::until(
$stopped,
nqp::stmts(
($stopped = 1),
nqp::handle(
target.push(&!block($pulled)),
'LABELED', $!label,
'REDO', ($stopped = 0),
'NEXT', nqp::null, # need NEXT for next LABEL support
'LAST', return
)
),
:nohandler
)
)
)
}

method sink-all(--> IterationEnd) {
my $pulled;
my int $stopped;
nqp::until(
nqp::eqaddr(($pulled := $!source.pull-one),IterationEnd),
nqp::stmts(
($stopped = 0),
nqp::until(
$stopped,
nqp::stmts(
($stopped = 1),
nqp::handle(
&!block($pulled),
'LABELED', $!label,
'REDO', ($stopped = 0),
'NEXT', nqp::null, # need NEXT for next LABEL support
'LAST', return
)
),
:nohandler
)
)
)
}
}

my class IterateOneWithoutPhasers does Rakudo::SlippyIterator {
has &!block;
has $!source;
Expand Down Expand Up @@ -810,24 +710,18 @@ Consider using a block if any of these are necessary for your mapping code."
}
}

sub sequential-map(\source, &block, \label) {
sub sequential-map(\source, &code, \label) {
# We want map to be fast, so we go to some effort to build special
# case iterators that can ignore various interesting cases.
my $count := &block.count;

Seq.new(
nqp::istype(&block,Block) && &block.has-phasers
?? $count < 2 || $count === Inf
?? IterateOneWithPhasers.new(&block,source,label)
!! IterateMoreWithPhasers.new(&block,source,$count,label)
!! $count < 2 || $count === Inf
?? nqp::istype(Slip,&block.returns)
?? IterateOneWithoutPhasers.new(&block,source,label)
!! IterateOneNotSlippingWithoutPhasers.new(&block,source,label)
!! $count == 2
?? IterateTwoWithoutPhasers.new(&block,source,label)
!! IterateMoreWithPhasers.new(&block,source,$count,label)
)
my $count := &code.count;

Seq.new: $count < 2 || $count == Inf
?? &code.has-phasers
?? IterateOneWithPhasers.new(&code, source, label)
!! IterateOneWithoutPhasers.new(&code, source, label)
!! $count > 2 || &code.has-phasers
?? IterateMoreWithPhasers.new(&code, source, $count, label)
!! IterateTwoWithoutPhasers.new(&code, source, label)
}

proto method flatmap (|) is nodal {*}
Expand Down
6 changes: 3 additions & 3 deletions src/core.c/ForeignCode.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ my class ForeignCode
# class ForeignCode
# has Code $!do; # Code object we delegate to

method arity() { self.signature.arity }

method count() { self.signature.count }
method arity( --> 0) { }
method count( --> Inf) { }
method has-phasers(--> False) { }

method signature(ForeignCode:D:) { (sub (|) { }).signature }

Expand Down
2 changes: 2 additions & 0 deletions src/core.c/WhateverCode.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ my class WhateverCode is Code {
multi method ACCEPTS(WhateverCode:D: \value) is raw {
nqp::call(nqp::getattr(self,Code,'$!do'),value)
}

method has-phasers(--> False) { }
}

# vim: expandtab shiftwidth=4

0 comments on commit a8f144c

Please sign in to comment.