Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make .unique about 2x / 3x faster
2x for pull-one situation, 3x for push-all situations
  • Loading branch information
lizmat committed Sep 23, 2015
1 parent 62a5033 commit 1acccc2
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions src/core/Any-iterable-methods.pm
Expand Up @@ -664,15 +664,40 @@ augment class Any {

proto method unique(|) is nodal {*}
multi method unique() {
my $seen := nqp::hash();
my str $target;
gather self.map: {
$target = nqp::unbox_s($_.WHICH);
unless nqp::existskey($seen, $target) {
nqp::bindkey($seen, $target, 1);
take $_;
Seq.new(class :: does Iterator {
has Mu $!iter;
has $!seen;
method BUILD(\list) {
$!iter = as-iterable(list).iterator;
$!seen := nqp::hash();
self
}
}
method new(\list) { nqp::create(self).BUILD(list) }
method pull-one() {
my Mu $value;
my str $needle;
until ($value := $!iter.pull-one) =:= IterationEnd {
$needle = nqp::unbox_s($value.WHICH);
unless nqp::existskey($!seen, $needle) {
nqp::bindkey($!seen, $needle, 1);
return $value;
}
}
IterationEnd
}
method push-all($target) {
my Mu $value;
my str $needle;
until ($value := $!iter.pull-one) =:= IterationEnd {
$needle = nqp::unbox_s($value.WHICH);
unless nqp::existskey($!seen, $needle) {
nqp::bindkey($!seen, $needle, 1);
$target.push($value);
}
}
IterationEnd
}
}.new(self))
}
multi method unique( :&as!, :&with! ) {
my @seen; # should be Mu, but doesn't work in settings :-(
Expand Down

0 comments on commit 1acccc2

Please sign in to comment.