From: Bruce Williams Date: 2002-09-23T14:30:07+09:00 Subject: Re: Getting a directory tree Hal, The following is a performance test (using profile.rb and Linux' 'time') of... My implementation: --snip-- require 'profile' def getdirs root Dir["#{root}/**/*"].select{ |file| test ?d, file and not test ?l, file } end getdirs '/home/iusris/devel' --snip-- which uses the recursive ** Dir glob (of Zsh fame). And the modified implementation suggested earlier (with a symlink-killer and a single flatten): --snip-- require 'profile' SEP = '/' def getdirs(root) return [] if test ?l, root dirs = Dir.entries(root) - [".", ".."] temp = dirs.map {|d| root+SEP+d}.select {|d| test(?d,d)} temp + temp.map {|x| getdirs(x) } end getdirs('/home/iusris/devel').flatten --snip-- with the following results: [MINE]: iusris@codedbliss[~/ruby/sandbox] time ruby getdirs.rb % cumulative self self total time seconds seconds calls ms/call ms/call name 40.84 1.07 1.07 1 1070.00 1500.00 Array#select 30.53 1.87 0.80 1 800.00 1110.00 Dir#[] 16.41 2.30 0.43 1230 0.35 0.35 Kernel.test 11.83 2.61 0.31 1089 0.28 0.28 String#allocate 0.00 2.61 0.00 1 0.00 0.00 Module#method_added 0.00 2.61 0.00 1 0.00 2610.00 Object#getdirs 0.00 2.61 0.00 1 0.00 2620.00 #toplevel 0.00 2.61 0.00 2 0.00 0.00 Array#allocate ruby getdirs.rb 2.82s user 0.53s system 648% cpu 0.516 total [PREVIOUSLY SUGGESTED]: iusris@codedbliss[~/ruby/sandbox] time ruby getdirs2.rb % cumulative self self total time seconds seconds calls ms/call ms/call name 33.71 9.53 9.53 147 64.83 104.83 Array#- 20.55 15.34 5.81 13834 0.42 0.42 String#== 9.44 18.01 2.67 294 9.08 388.50 Array#map 9.20 20.61 2.60 2230 1.17 1.64 String#+ 6.69 22.50 1.89 3935 0.48 0.48 String#allocate 4.60 23.80 1.30 147 8.84 922.52 Object#getdirs 4.03 24.94 1.14 147 7.76 12.79 Dir#each 3.93 26.05 1.11 147 7.55 12.11 Array#select 2.51 26.76 0.71 1262 0.56 0.56 Kernel.test 2.19 27.38 0.62 1031 0.60 0.60 Array#allocate 0.88 27.63 0.25 147 1.70 16.19 Dir#entries 0.64 27.81 0.18 411 0.44 0.44 Fixnum#== 0.60 27.98 0.17 1 170.00 350.00 Array#flatten 0.50 28.12 0.14 147 0.95 1.36 Array#+ 0.42 28.24 0.12 147 0.82 14.29 Enumerable.to_a 0.11 28.27 0.03 147 0.20 0.20 Dir#open 0.00 28.27 0.00 1 0.00 28270.00 #toplevel 0.00 28.27 0.00 1 0.00 0.00 Module#method_added ruby getdirs2.rb 28.51s user 0.39s system 373% cpu 7.734 total As you can see, the previously suggested version takes about 10x longer to complete. -- I call this technique "Glob-orific and Short-tacular" ~ Bruce -- _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ Bruce Williams http://www.codedbliss.com iusris/#ruby-lang bruce@codedbliss.com _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/