Ruby comes with a code profiler (documentation begins on
on page 454). In and of itself, that isn't too surprising,
but when you realize that the profiler is written in just about 50
lines of Ruby, that makes
for a pretty impressive language.
You can add profiling to your code using the command-line option
-r
profile
, or from within the code using
require
"profile"
. For example:
require "profile"
class Peter
def initialize(amt)
@value = amt
end
def rob(amt)
@value -= amt
amt
end
end
class Paul
def initialize
@value = 0
end
def pay(amt)
@value += amt
amt
end
end
peter = Peter.new(1000)
paul = Paul.new
1000.times do
paul.pay(peter.rob(10))
end
|
Run this, and you'll get something like the following.
time seconds seconds calls ms/call ms/call name
32.14 0.27 0.27 1 270.00 840.00 Fixnum#times
30.95 0.53 0.26 1000 0.26 0.27 Paul#pay
29.76 0.78 0.25 1000 0.25 0.30 Peter#rob
5.95 0.83 0.05 1000 0.05 0.05 Fixnum#-
1.19 0.84 0.01 1000 0.01 0.01 Fixnum#+
0.00 0.84 0.00 1 0.00 0.00 Paul#initialize
0.00 0.84 0.00 2 0.00 0.00 Class#inherited
0.00 0.84 0.00 4 0.00 0.00 Module#method_added
0.00 0.84 0.00 1 0.00 0.00 Peter#initialize
0.00 0.84 0.00 1 0.00 840.00 #toplevel
0.00 0.84 0.00 2 0.00 0.00 Class#new
|
With the profiler, you can quickly identify and fix bottlenecks.
Remember to check the code without the profiler afterward,
though---sometimes the slowdown the profiler introduces can mask other
problems.
Ruby is a wonderfully transparent and expressive language, but it does
not relieve the programmer of the need to apply common sense: creating
unnecessary objects, performing unneeded work, and creating generally
bloated code are wasteful in any language.
Debugger commands
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. |
|
|