Skip to content

Commit

Permalink
optimize Range.roll, and Range.pick if the number of range elems is m…
Browse files Browse the repository at this point in the history
…uch larger than the number of elements to pick
  • Loading branch information
moritz committed Jan 17, 2012
1 parent 0ac25d0 commit aa1d8b6
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions src/core/Range.pm
Expand Up @@ -126,6 +126,45 @@ class Range is Iterable does Positional {
~ ':max(' ~ DUMP($!max) ~ ')'
~ ')'
}

proto method roll(|$) { * }
multi method roll(Range:D: Whatever) {
gather loop { take self.roll }
}
multi method roll(Range:D:) {
nextsame unless $!min.^isa(Int) && $!max.^isa(Int);
my Int:D $least = $!excludes_min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes_max ?? $!max - 1 !! $!max);
$elems ?? ($least + $elems.rand.floor) !! Any;
}
multi method roll($num as Int) {
nextsame unless $!min.^isa(Int) && $!max.^isa(Int);
return self.roll if $num == 1;
my int $n = nqp::unbox_i($num);
gather loop (my int $i = 0; $i < $n; $i = $i + 1) {
take self.roll;
}
}

proto method pick(|$) { * }
multi method pick() { self.roll };
multi method pick(Whatever) { self.list.pick };
multi method pick($n as Int) {
nextsame unless $!min.^isa(Int) && $!max.^isa(Int);
my Int:D $least = $!excludes_min ?? $!min + 1 !! $!min;
my Int:D $elems = 1 + ($!excludes_max ?? $!max - 1 !! $!max);
nextsame unless $elems > 3 * $n;
my %seen;
my int $i_n = nqp::unbox_i($n);
gather while $i_n > 0 {
my Int $x = $least + $elems.rand.floor;
unless %seen{$x} {
%seen{$x} = 1;
$i_n = $i_n - 1;
take $x;
}
}
}
}


Expand Down

0 comments on commit aa1d8b6

Please sign in to comment.