From: matz@... (Yukihiro Matsumoto) Date: 2001-02-14T04:03:14+09:00 Subject: [ruby-talk:10794] Re: perform. of Dir["**/*"] Hi, In message "[ruby-talk:10778] perform. of Dir["**/*"]" on 01/02/13, "Richard Hensh" writes: |Now that someone has straightened me out on the use of **, I have a |performance question. Running the following script on my C: drive took about |497 seconds. The drive contains 32701 files. Is this slow? Slow. Since it had to create 32701 string objects, GC intervals became burden. On my Linux box, % ruby -e 'p Dir.glob("**/*").length' took 1m43sec. OTOH, % ruby -e 'GC.disable; p Dir.glob("**/*").length' took 1m13sec. Then I hacked to reduce memory consumption by using block, so that now % ruby -e 'GC.disable; n = 0; p Dir.glob("**/*"){n+=1}; p n' takes 4.08sec. Here's the patch from the latest. matz. --- dir.c~ Mon Nov 20 10:24:22 2000 +++ dir.c Wed Feb 14 03:29:05 2001 @@ -679,7 +709,14 @@ char *path; VALUE ary; { - rb_ary_push(ary, rb_tainted_str_new2(path)); + VALUE str = rb_tainted_str_new2(path); + + if (ary) { + rb_ary_push(ary, str); + } + else { + rb_yield(str); + } } static void @@ -753,10 +790,12 @@ char buffer[MAXPATHLEN], *buf = buffer; char *t; int nest; - VALUE ary; + VALUE ary = 0; Check_SafeStr(str); - ary = rb_ary_new(); + if (!rb_block_given_p()) { + ary = rb_ary_new(); + } if (RSTRING(str)->len >= MAXPATHLEN) buf = xmalloc(RSTRING(str)->len + 1); @@ -783,14 +826,6 @@ } if (buf != buffer) free(buf); - if (rb_block_given_p()) { - long len = RARRAY(ary)->len; - VALUE *ptr = RARRAY(ary)->ptr; - - while (len--) { - rb_yield(*ptr++); - } - } return ary; }