Code Listing: stat_bench.rb
# benchmark to test if File.directory? first is faster than
# Dir.entries followed by catching and raising an exception.
require 'benchmark'
include Benchmark
def entries_with_exception(dir)
Dir.entries(dir).size
rescue Errno::ENOENT
0
end
def entries_after_stat(dir)
if File.directory?(dir)
Dir.entries(dir).size
else
0
end
end
def entries(dirs, method, opts = {})
# drop disk cache on Linux
`sync && echo 3 | sudo tee /proc/sys/vm/drop_caches` if opts[:drop_cache]
dirs.inject(0) do |sum, dir|
sum + send(method, dir)
end
end
def compare(dirs, opts = {}) # dirs, n = 6, drop_cache = false)
n = opts[:n] || 6
benchmark(CAPTION, 10, FORMAT, '>excep avg', '>stat avg') do |x|
e_timings = [] # with_exception timings
s_timings = [] # after_stat timings
n.times do
e_timings << x.report('excep') { entries(dirs, :entries_with_exception, opts) }
s_timings << x.report('stat ') { entries(dirs, :entries_after_stat, opts) }
end
[e_timings.inject(&:+)/n, s_timings.inject(&:+)/n]
end
end
root = '/usr/lib'
dirs = `find #{root} -type d`.split($/).shuffle
no_dirs = dirs.map{|d| d + 'nope'}
puts '=== warming up ==='
20.times do
entries(dirs, :entries_with_exception)
entries(no_dirs, :entries_with_exception)
entries(dirs, :entries_after_stat)
entries(no_dirs, :entries_after_stat)
end
puts "=== testing with #{dirs.length} dirs in #{root} ==="
compare(dirs)
puts '=== now with non-existent directories ==='
compare(no_dirs)
puts '=== drop the disk cache ==='
compare(dirs, :drop_cache => true)
puts '=== now with non-existent directories ==='
compare(no_dirs, :drop_cache => true)
Ruby 1.9.3-p194 raw data
=== warming up ===
=== testing with 2449 dirs in /usr/lib ===
user system total real
excep 0.030000 0.040000 0.070000 ( 0.069843)
stat 0.050000 0.030000 0.080000 ( 0.078254)
excep 0.030000 0.040000 0.070000 ( 0.071451)
stat 0.040000 0.030000 0.070000 ( 0.077277)
excep 0.030000 0.050000 0.080000 ( 0.069525)
stat 0.030000 0.050000 0.080000 ( 0.079875)
excep 0.010000 0.050000 0.060000 ( 0.069462)
stat 0.020000 0.050000 0.070000 ( 0.077389)
excep 0.020000 0.050000 0.070000 ( 0.069943)
stat 0.030000 0.050000 0.080000 ( 0.079212)
excep 0.030000 0.040000 0.070000 ( 0.069370)
stat 0.010000 0.070000 0.080000 ( 0.078848)
>excep avg 0.025000 0.045000 0.070000 ( 0.069932)
>stat avg 0.030000 0.046667 0.076667 ( 0.078476)
=== now with non-existent directories ===
user system total real
excep 0.080000 0.010000 0.090000 ( 0.088597)
stat 0.010000 0.000000 0.010000 ( 0.007701)
excep 0.080000 0.000000 0.080000 ( 0.090979)
stat 0.000000 0.010000 0.010000 ( 0.007933)
excep 0.080000 0.010000 0.090000 ( 0.090116)
stat 0.010000 0.000000 0.010000 ( 0.007656)
excep 0.090000 0.000000 0.090000 ( 0.089195)
stat 0.000000 0.010000 0.010000 ( 0.007738)
excep 0.080000 0.010000 0.090000 ( 0.091830)
stat 0.000000 0.010000 0.010000 ( 0.007665)
excep 0.080000 0.010000 0.090000 ( 0.089698)
stat 0.010000 0.000000 0.010000 ( 0.007713)
>excep avg 0.081667 0.006667 0.088333 ( 0.090069)
>stat avg 0.005000 0.005000 0.010000 ( 0.007734)
=== drop the disk cache ===
user system total real
excep 0.090000 0.250000 0.460000 ( 12.241728)
stat 0.110000 0.200000 0.380000 ( 11.444665)
excep 0.070000 0.270000 0.410000 ( 11.554205)
stat 0.100000 0.210000 0.390000 ( 11.102887)
excep 0.080000 0.260000 0.410000 ( 12.195852)
stat 0.110000 0.190000 0.370000 ( 11.511162)
excep 0.090000 0.260000 0.430000 ( 12.495996)
stat 0.090000 0.220000 0.390000 ( 10.402701)
excep 0.100000 0.230000 0.410000 ( 11.645824)
stat 0.100000 0.210000 0.380000 ( 10.886361)
excep 0.090000 0.250000 0.410000 ( 12.645786)
stat 0.090000 0.220000 0.380000 ( 10.524727)
>excep avg 0.086667 0.253333 0.421667 ( 12.129898)
>stat avg 0.100000 0.208333 0.381667 ( 10.978750)
=== now with non-existent directories ===
user system total real
excep 0.180000 0.120000 0.380000 ( 4.878866)
stat 0.010000 0.100000 0.180000 ( 5.034120)
excep 0.190000 0.110000 0.370000 ( 5.225184)
stat 0.010000 0.100000 0.160000 ( 4.865224)
excep 0.200000 0.080000 0.350000 ( 4.906489)
stat 0.010000 0.080000 0.150000 ( 4.834200)
excep 0.220000 0.080000 0.370000 ( 4.748225)
stat 0.020000 0.080000 0.160000 ( 4.565369)
excep 0.210000 0.100000 0.390000 ( 5.325185)
stat 0.020000 0.090000 0.180000 ( 5.298778)
excep 0.210000 0.080000 0.360000 ( 4.925327)
stat 0.010000 0.090000 0.160000 ( 4.842326)
>excep avg 0.201667 0.095000 0.370000 ( 5.001546)
>stat avg 0.013333 0.090000 0.165000 ( 4.906669)
JRuby 1.7.0 raw data
=== testing with 2449 dirs in /usr/lib ===
user system total real
excep 0.130000 0.050000 0.180000 ( 0.165000)
stat 0.150000 0.090000 0.240000 ( 0.226000)
excep 0.100000 0.070000 0.170000 ( 0.163000)
stat 0.140000 0.040000 0.180000 ( 0.183000)
excep 0.110000 0.040000 0.150000 ( 0.160000)
stat 0.110000 0.080000 0.190000 ( 0.181000)
excep 0.120000 0.030000 0.150000 ( 0.156000)
stat 0.090000 0.090000 0.180000 ( 0.182000)
excep 0.130000 0.030000 0.160000 ( 0.159000)
stat 0.100000 0.070000 0.170000 ( 0.181000)
excep 0.110000 0.050000 0.160000 ( 0.157000)
stat 0.130000 0.050000 0.180000 ( 0.181000)
>excep avg 0.116667 0.045000 0.161667 ( 0.160000)
>stat avg 0.120000 0.070000 0.190000 ( 0.189000)
=== now with non-existent directories ===
user system total real
excep 1.570000 0.020000 1.590000 ( 0.918000)
stat 0.020000 0.010000 0.030000 ( 0.032000)
excep 0.710000 0.000000 0.710000 ( 0.689000)
stat 0.030000 0.010000 0.040000 ( 0.026000)
excep 0.680000 0.020000 0.700000 ( 0.695000)
stat 0.020000 0.000000 0.020000 ( 0.016000)
excep 0.650000 0.010000 0.660000 ( 0.667000)
stat 0.010000 0.000000 0.010000 ( 0.015000)
excep 0.730000 0.010000 0.740000 ( 0.677000)
stat 0.010000 0.010000 0.020000 ( 0.016000)
excep 0.660000 0.010000 0.670000 ( 0.666000)
stat 0.000000 0.010000 0.010000 ( 0.016000)
>excep avg 0.833333 0.011667 0.845000 ( 0.718667)
>stat avg 0.015000 0.006667 0.021667 ( 0.020167)
=== drop the disk cache ===
user system total real
excep 0.600000 0.320000 1.300000 ( 15.008000)
stat 0.430000 0.290000 0.800000 ( 12.328000)
excep 0.610000 0.330000 1.030000 ( 12.377000)
stat 0.870000 0.340000 1.300000 ( 12.411000)
excep 0.560000 0.300000 0.940000 ( 11.877000)
stat 0.480000 0.350000 0.930000 ( 12.946000)
excep 0.370000 0.260000 0.720000 ( 12.027000)
stat 0.470000 0.340000 0.890000 ( 12.719000)
excep 0.350000 0.300000 0.730000 ( 14.082000)
stat 0.420000 0.320000 0.840000 ( 14.975000)
excep 0.290000 0.410000 0.800000 ( 12.136000)
stat 0.400000 0.290000 0.770000 ( 12.154000)
>excep avg 0.463333 0.320000 0.920000 ( 12.917833)
>stat avg 0.511667 0.321667 0.921667 ( 12.922167)
=== now with non-existent directories ===
user system total real
excep 1.600000 0.130000 1.820000 ( 7.417000)
stat 0.060000 0.130000 0.270000 ( 5.766000)
excep 1.720000 0.180000 1.970000 ( 7.100000)
stat 0.110000 0.090000 0.270000 ( 6.099000)
excep 1.640000 0.150000 1.870000 ( 7.107000)
stat 0.070000 0.110000 0.250000 ( 5.497000)
excep 1.630000 0.120000 1.830000 ( 6.859000)
stat 0.060000 0.140000 0.270000 ( 5.542000)
excep 1.780000 0.150000 1.990000 ( 7.237000)
stat 0.080000 0.110000 0.270000 ( 5.483000)
excep 1.490000 0.150000 1.730000 ( 7.019000)
stat 0.070000 0.110000 0.240000 ( 5.280000)
>excep avg 1.643333 0.146667 1.868333 ( 7.123167)
>stat avg 0.075000 0.115000 0.261667 ( 5.611167)