如何阅读 ruby 分析器的输出
How to read ruby profiler's output
让我们从docs中举个例子:
require 'profile'
def slow_method
5000.times do
9999999999999999*999999999
end
end
def fast_method
5000.times do
9999999999999999+999999999
end
end
slow_method
fast_method
输出:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
68.42 0.13 0.13 2 65.00 95.00 Integer#times
15.79 0.16 0.03 5000 0.01 0.01 Fixnum#*
15.79 0.19 0.03 5000 0.01 0.01 Fixnum#+
0.00 0.19 0.00 2 0.00 0.00 IO#set_encoding
0.00 0.19 0.00 1 0.00 100.00 Object#slow_method
0.00 0.19 0.00 2 0.00 0.00 Module#method_added
0.00 0.19 0.00 1 0.00 90.00 Object#fast_method
0.00 0.19 0.00 1 0.00 190.00 #toplevel
% time
是在这些方法中花费的时间。
cumulative seconds
是前面的cumulative seconds
加上self seconds
,即0 + 0.13 = 0.13
、0.13 + 0.03 = 0.16
、0.16 + 0.03 = 0.19
等。
self seconds
% time
以秒为单位。
calls
表示该方法被调用了多少次。
self ms/call
是 self seconds
/ calls
.
- 什么是
total ms/call
?
一个方法可能会自己花费时间,或者由于它调用的方法所花费的时间而花费时间。 self ms/call
只计算前者,而total ms/call
计算两者之和。代表 self seconds
是有意义的,但不是 total seconds
因为那会在整个地方累积。
tl;dr self seconds
+ 在调用方法中花费的时间
好吧,让我们深入source. There are two proc
s, gathering information there: PROFILE_CALL_PROC
, PROFILE_RETURN_PROC
。前者在进入方法之前被调用,后者在退出之前被调用。
@@maps[Thread.current]
积累方法信息,即calls
, total seconds
(cost
), self seconds
and name
in this particular order. This very information is served later to the user, in a more wordy fashion. After being aggregated.
@@stacks[Thread.current]
在堆栈中存储有关方法 运行 的信息。即 "when the method was started" 和 "how much time does called (child) methods took" (tick[1]
)。这更像是一个临时数据结构,旨在帮助将数据收集到 @@maps
.
正如人们现在可以看到的那样,self seconds
is total seconds
minus cost
(花在被调用方法上的时间)。也就是说,total seconds
是花在方法本身和它调用的方法上的时间。
P.S。几乎让人想起 ruby-prof
.
中的 flat profiles
让我们从docs中举个例子:
require 'profile'
def slow_method
5000.times do
9999999999999999*999999999
end
end
def fast_method
5000.times do
9999999999999999+999999999
end
end
slow_method
fast_method
输出:
% cumulative self self total
time seconds seconds calls ms/call ms/call name
68.42 0.13 0.13 2 65.00 95.00 Integer#times
15.79 0.16 0.03 5000 0.01 0.01 Fixnum#*
15.79 0.19 0.03 5000 0.01 0.01 Fixnum#+
0.00 0.19 0.00 2 0.00 0.00 IO#set_encoding
0.00 0.19 0.00 1 0.00 100.00 Object#slow_method
0.00 0.19 0.00 2 0.00 0.00 Module#method_added
0.00 0.19 0.00 1 0.00 90.00 Object#fast_method
0.00 0.19 0.00 1 0.00 190.00 #toplevel
% time
是在这些方法中花费的时间。cumulative seconds
是前面的cumulative seconds
加上self seconds
,即0 + 0.13 = 0.13
、0.13 + 0.03 = 0.16
、0.16 + 0.03 = 0.19
等。self seconds
% time
以秒为单位。calls
表示该方法被调用了多少次。self ms/call
是self seconds
/calls
.- 什么是
total ms/call
?
一个方法可能会自己花费时间,或者由于它调用的方法所花费的时间而花费时间。 self ms/call
只计算前者,而total ms/call
计算两者之和。代表 self seconds
是有意义的,但不是 total seconds
因为那会在整个地方累积。
tl;dr self seconds
+ 在调用方法中花费的时间
好吧,让我们深入source. There are two proc
s, gathering information there: PROFILE_CALL_PROC
, PROFILE_RETURN_PROC
。前者在进入方法之前被调用,后者在退出之前被调用。
@@maps[Thread.current]
积累方法信息,即calls
, total seconds
(cost
), self seconds
and name
in this particular order. This very information is served later to the user, in a more wordy fashion. After being aggregated.
@@stacks[Thread.current]
在堆栈中存储有关方法 运行 的信息。即 "when the method was started" 和 "how much time does called (child) methods took" (tick[1]
)。这更像是一个临时数据结构,旨在帮助将数据收集到 @@maps
.
正如人们现在可以看到的那样,self seconds
is total seconds
minus cost
(花在被调用方法上的时间)。也就是说,total seconds
是花在方法本身和它调用的方法上的时间。
P.S。几乎让人想起 ruby-prof
.