diff --git a/ChangeLog b/ChangeLog index 39e07c7798..1c59dc475a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Wed Aug 20 16:39:59 2008 Nobuyoshi Nakada + + * array.c (rb_ary_sample): performance improvement for huge array. + Wed Aug 20 12:28:31 2008 Nobuyoshi Nakada * array.c (rb_ary_sample): get rid of infinite loop. #455 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