diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2025-12-20 13:48:10 +0100 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2026-02-12 15:52:42 +0100 |
| commit | 3b5ee7488c8064cd3b1afc41bc43afdb907fdf16 (patch) | |
| tree | f89f2b23ef11412d6afb16b20b4057fd17c8c731 /test/ruby/test_rubyoptions.rb | |
| parent | e26bef571c3c916826fdd2f468dea7ca41369f8e (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/ruby/test_rubyoptions.rb')
0 files changed, 0 insertions, 0 deletions
