views:

120

answers:

3

I have a bunch of rspec tests that are taking entirely too long to run. I am trying to figure out where the bottleneck is and the logical place to start is using the standard libraries profile library. Execution is happening with JRuby 1.5.2 in this particular case. Here is the output after embedding the profile library in my spec:

 %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
  0.37     0.37      0.37       69     5.33     5.33  #<Class:#<Object:0x99b2a1d>>#include
  0.01     0.38      0.01      208     0.06     0.06  String#fast_xs
  0.00    98.99      0.00        1     0.00 98987.00  #toplevel

I need to look into why 208 calls are being made to String#fast_xs, but the real question here is what exactly is happening in #toplevel? There is a latency of 98987.00ms being spent on something in there and I need a more granular way of seeing the breakdown to understand what I can change in my spec tests to speed things up.

A: 

How many tests do you have? Each RSpec test reloads the whole Rails environment, so if you have tons of tests the overhead is most likely from that. You could look at the Spork testing server that only loads the environment once when you run your tests.

The Ruby on Rails Tutorial Book recommends using Spork if you are doing lots of testing and are running into problems with slow tests.

Jergason
Unless there is a fork for Spork (no pun intended) for JRuby, I don't think Spork works well with JRuby as it currently stands.
randombits
D'oh! Sorry, missed that little detail.
Jergason
This spork might work: http://github.com/rdp/spork
rogerdpack
A: 

There are so many questions like this. Some profile output is shown, and the question: "What's going on?"

There's no need to puzzle over the profile output. You can find the problem(s) right away. The more time they take, the easier they are to find.

Anything that deals in self-time, ms-per-call, call counts, etc. is stuck in the pit of performance myths.

Added: For example

  • self time (exclusive) is based on the premise that the only way you can waste time is by not calling functions. When functions are called unnecessarily, that you'd like to find and get rid of, or if IO is done unnecessarily, it doesn't show up in self time. IO and other blocking time doesn't show up at all if samples are only taken when the program is unblocked.

  • ms-per-call (inclusive), multiplied by call count of a function, divided by total time, gives fraction of time the function is responsible for. With only two of these three numbers you can't tell if the function is spending too much time or not.

  • If you can tell if a function is responsible for a good fraction of time, you still need to find the lines within it that are responsible for the time. If the profiler acts like the only units you care about are functions, you're still left doing detective work.

Mike Dunlavey
For some comments on the technique Mike's suggesting: see [One could use a profiler, but why not just halt the program?](http://stackoverflow.com/questions/266373/one-could-use-a-profiler-but-why-not-just-halt-the-program)
Andrew Grimm
@Andrew: @randombits: That was my first attempt to introduce the issue. Since then I've refined the explanation and addressed the kinds of objections that people tend to raise. A number of other people have independently come to the same position, but don't seem to be driven to bother telling people about it, perhaps because they weren't academics, as I was.
Mike Dunlavey
@Andrew: @randombits: I'm thinking in particular of these: (http://stackoverflow.com/questions/266373/one-could-use-a-profiler-but-why-not-just-halt-the-program/317160#317160) (http://stackoverflow.com/questions/2473666/tips-for-optimizing-c-net-programs/2474118#2474118) (http://www.rotateright.com/) (http://www.lw-tech.com/) They do stack sampling, on wall-time, and report percents by line, and ignore recursion.
Mike Dunlavey
A: 

there is jruby-prof gem that might help you. The ruby-prof gem for MRI might help excellently as well.

rogerdpack