summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-12-20 13:48:10 +0100
committerJean Boussier <jean.boussier@gmail.com>2026-02-12 15:52:42 +0100
commit3b5ee7488c8064cd3b1afc41bc43afdb907fdf16 (patch)
treef89f2b23ef11412d6afb16b20b4057fd17c8c731 /test
parente26bef571c3c916826fdd2f468dea7ca41369f8e (diff)
Dir.scan: return or yield children along with their type
[Feature #21800] There are numerous ruby tools that need to recursively scan the project directory, such as Zeitwerk, rubocop, etc. All of them end up listing childs of a directory then for each child emit a `stat` call to check if it's a directory or not. This is common enough for a pattern that on most operating systems, `struct dirent` include a `dtype` member that allows to check the file type without issuing a any extra system calls. By yielding that type, we can make these routines twice as fast. ``` $ hyperfine './miniruby --disable-all --yjit ../test.rb' 'OPT=1 ./miniruby --disable-all --yjit ../test.rb' Benchmark 1: ./miniruby --disable-all --yjit ../test.rb Time (mean ± σ): 1.428 s ± 0.062 s [User: 0.342 s, System: 1.070 s] Range (min … max): 1.396 s … 1.601 s 10 runs Benchmark 2: OPT=1 ./miniruby --disable-all --yjit ../test.rb Time (mean ± σ): 673.8 ms ± 5.8 ms [User: 146.0 ms, System: 527.3 ms] Range (min … max): 659.7 ms … 679.6 ms 10 runs Summary OPT=1 ./miniruby --disable-all --yjit ../test.rb ran 2.12 ± 0.09 times faster than ./miniruby --disable-all --yjit ../test.rb ``` ```ruby if ENV['OPT'] def count_ruby_files count = 0 queue = [File.expand_path(__dir__)] while dir = queue.pop Dir.scan(dir) do |name, type| next if name.start_with?(".") case type when :directory queue << File.join(dir, name) when :file count += 1 if name.end_with?(".rb") end end end count end else def count_ruby_files count = 0 queue = [File.expand_path(__dir__)] while dir = queue.pop Dir.each_child(dir) do |name| next if name.start_with?(".") abspath = File.join(dir, name) if File.directory?(abspath) queue << abspath else count += 1 if name.end_with?(".rb") end end end count end end 10.times do count_ruby_files end ```
Diffstat (limited to 'test')
0 files changed, 0 insertions, 0 deletions