I´m gonna keep it simple: Ruby has an excellent native debugger, that runs when you insert the -r debug parameter when calling the interpreter, such as this:

ruby -r debug [debug options] [program file] [program arguments]

Debugger commands are:

b[reak] [file:]line Set breakpoint at given line in file (default current file).
b[reak] [file:]name Set breakpoint at method in file.
b[reak] Display breakpoints and watchpoints.
wat[ch] expr Break when expression becomes true.
del[ete] [nnn] Delete breakpoint nnn (default all).
disp[lay] expr Display value of nnn every time debugger gets control.
disp[lay] Show current displays.
undisp[lay] [nnn] Remove display (default all).
c[ont] Continue execution.
s[tep] nnn=1 Execute next nnn lines, stepping into methods.
n[ext] nnn=1 Execute next nnn lines, stepping over methods.
fi[nish] Finish execution of the current function.
q[uit] Exit the debugger.
w[here] Display current stack frame.
f[rame] Synonym for where.
l[ist] [start–end] List source lines from start to end.
up nnn=1 Move up nnn levels in the stack frame.
down nnn=1 Move down nnn levels in the stack frame.
v[ar] g[lobal] Display global variables.
v[ar] l[ocal] Display local variables.
v[ar] i[stance] obj Display instance variables of obj.
v[ar] c[onst] Name Display constants in class or module name.
m[ethod] i[nstance] obj Display instance methods of obj.
m[ethod] Name Display instance methods of the class or module name.
th[read] l[ist] List all threads.
th[read] [c[ur[rent]]] Display status of current thread.
th[read] [c[ur[rent]]] nnn Make thread nnn current and stop it.
th[read] stop nnn Make thread nnn current and stop it.
th[read] resume nnn Resume thread nnn.
[p] expr Evaluate expr in the current context. expr may include assignment to variables and method invocations.
empty A null command repeats the last command.

Source: PickAxe

When searching for bottlenecks, your best bet is to use the benchmark module to check the execution of code chunks. The best thing to learn how to deal with the benchmark module is checking its documentation here.

There´s also an easy way to track your code execution: The profiler. To run it, you should just put the -r profile parameter when calling the interpreter.

ruby -r profile [program file] [program arguments]

Seems like an easy way to track down those nasty bottlenecks! Still, the best way to ensure great performance is to keep your code clean and avoid creating unnecessary crap!

Hope I remember this when running after my slow applications cemeteries!