# New Ticket Created by Tadeusz SoĊnierz # Please include the string: [perl #77204] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt3/Ticket/Display.html?id=77204 >
(1..n) is a common idiom to get a random number between 1 and n. However, due to Range and .pick complexity it is much slower than (n.rand + 1). This patch optimizes Range.pick behaviour in a specific case, when both edges of the Range are Integers. Otherwise, and in case of using :replace, the Any-List.pm .pick implementation is used. Kind regards, Ted
>From 41c37191b4ff458e811e41edadea1912a1657ea3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadeusz=20So=C5=9Bnierz?= <[email protected]> Date: Sat, 14 Aug 2010 00:24:14 +0000 Subject: [PATCH] Optimized Range.pick in some special cases --- src/core/Range.pm | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/src/core/Range.pm b/src/core/Range.pm index 0d3a920..6c6f092 100644 --- a/src/core/Range.pm +++ b/src/core/Range.pm @@ -58,6 +58,21 @@ class Range is Iterable does Positional { $min ~ $emin ~ ".." ~ $emax ~ $max; } + multi method pick() { + nextsame unless $.min.isa(Int) and $.max.isa(Int); + my $least = $.excludes_min ?? $.min + 1 !! $.min; + my $elems = ($.excludes_max ?? $.max - 1 !! $.max) - $least; + $elems ?? ($least + $elems.rand.floor) !! Any; + } + + multi method pick(Int $n) { + nextsame; + } + + multi method pick(Int $n, :$replace!) { + (1..$n).map: { self.pick } + } + multi method fmt($format = '%s', $separator = ' ') { self.map({ .fmt($format)}).join($separator); } -- 1.7.1.1
