Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make List.pick(*) about 7% faster
  • Loading branch information
lizmat committed Apr 24, 2015
1 parent 5efcae8 commit 7fe6f1b
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/core/List.pm
Expand Up @@ -181,6 +181,22 @@ my class List does Positional { # declared in BOOTSTRAP
my $elems = self.elems;
$elems ?? self.AT-POS($elems.rand.floor) !! Nil;
}
multi method pick(Whatever) {
fail X::Cannot::Infinite.new(:action<.pick from>) if self.infinite;

my Int $elems = self.elems;
return unless $elems;

my Mu $rpa := nqp::clone($!items);
my Int $i;
gather while $elems {
$i = nqp::rand_I(nqp::decont($elems), Int);
$elems = $elems - 1;
take-rw nqp::atpos($rpa,nqp::unbox_i($i));
# replace selected element with last unpicked one
nqp::bindpos($rpa,nqp::unbox_i($i),nqp::atpos($rpa,nqp::unbox_i($elems)));
}
}
multi method pick(\number) {
fail X::Cannot::Infinite.new(:action<.pick from>) if self.infinite;
## We use a version of Fisher-Yates shuffle here to
Expand Down

0 comments on commit 7fe6f1b

Please sign in to comment.