From ee5c9fb9831788344a5440e9151487d6f512be2e Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 20 Aug 2008 07:40:03 +0000 Subject: * array.c (rb_ary_sample): performance improvement for huge array. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18719 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- array.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 18 deletions(-) (limited to 'array.c') diff --git a/array.c b/array.c index d3dbde40d8..1f6140d265 100644 --- a/array.c +++ b/array.c @@ -3022,35 +3022,71 @@ rb_ary_shuffle(VALUE ary) static VALUE rb_ary_sample(int argc, VALUE *argv, VALUE ary) { - VALUE nv, result; - int n, len, i, j; + VALUE nv, result, *ptr; + long n, len, i, j, k, idx[10]; len = RARRAY_LEN(ary); if (argc == 0) { if (len == 0) return Qnil; - i = rb_genrand_real()*len; + i = len == 1 ? 0 : rb_genrand_real()*len; return RARRAY_PTR(ary)[i]; } rb_scan_args(argc, argv, "1", &nv); - n = NUM2INT(nv); + n = NUM2LONG(nv); + ptr = RARRAY_PTR(ary); + len = RARRAY_LEN(ary); if (n > len) n = len; - if (n == 0) return rb_ary_new2(0); - result = rb_ary_new2(n); - for (i=0; i k) { + if (p > j) p = j; + } + } while (++j < i); + idx[i] = k; + } + result = rb_ary_new2(n); + for (i=0; i