Andrew Grimm
Andrew Grimm

Reputation: 81500

Is it possible to profile for file system interaction in Ruby?

Is it possible to profile a Ruby application to see how much it interacts with the file system?

Background: In the past I've written code that reads files within a loop when it only needs to do so once. I'd like to make sure that I eliminate all such code.

Upvotes: 1

Views: 160

Answers (3)

Confusion
Confusion

Reputation: 16841

There are already perfectly capable programs for this purpose out there, that you don't need to duplicate. I don't think you should complicate your program with special logic checking for a relatively obscure programming error (at least, I've never accidentally committed the error you describe). In such cases, the solution is to check a performance characteristic from outside the program. Assuming you are on Linux, I would turn to a test/spec that exercises your code and watches iostat (or similar) in a seperate thread.

Upvotes: 1

Wayne Conrad
Wayne Conrad

Reputation: 107989

I'm a sucker for brute force.

File.open(path, 'r') do |file|
  ...
end
File.mv(path, path + '.hidden')    # Temporary

If the code tries to open the file twice, it won't find it the second time. After the test, you can reverse the rename with a shell one-liner. In Bash (and probably in other *nix shells as well):

for i in `ls *.hidden` ; do mv $i ${i%.hidden} ; done

Upvotes: 0

zetetic
zetetic

Reputation: 47548

Sure, you can simply require 'profile at the top of a script:

# myscript.rb
require 'profile'
Dir.entries(".").each  { |e| puts e}

$ ruby myscript.rb

(list of filenames...)

  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.00     0.00      0.00        1     0.00     0.00  Dir#open
  0.00     0.00      0.00        1     0.00     0.00  Dir#each
  0.00     0.00      0.00        1     0.00     0.00  Enumerable.to_a
  0.00     0.00      0.00        1     0.00     0.00  Dir#entries
  0.00     0.00      0.00       56     0.00     0.00  IO#write
  0.00     0.00      0.00       28     0.00     0.00  IO#puts
  0.00     0.00      0.00       28     0.00     0.00  Kernel.puts
  0.00     0.00      0.00        1     0.00     0.00  Array#each
  0.00     0.01      0.00        1     0.00    10.00  #toplevel

Or you can just pass in an option on the command line:

$ ruby -r profile myscript.rb

If you want finer control over what to profile, take a look at the ruby-prof library.

Upvotes: 1

Related Questions