【发布时间】:2011-11-07 07:57:58
【问题描述】:
我正在尝试优化一些代码,对来自summaryRprof() 的信息感到困惑。特别是,似乎对外部 C 程序进行了多次调用,但我无法确定 哪个 C 程序,来自哪个 R 函数。我计划通过对代码进行大量切片和切块来解决这个问题,但想知道我是否忽略了一些更好的方法来解释分析数据。
消耗最高的函数是.Call,这显然是对C代码调用的通用描述;下一个主要功能似乎是赋值操作:
$by.self
self.time self.pct total.time total.pct
".Call" 2281.0 54.40 2312.0 55.14
"[.data.frame" 145.0 3.46 218.5 5.21
"initialize" 123.5 2.95 217.5 5.19
"$<-.data.frame" 121.5 2.90 121.5 2.90
"as.vector" 110.5 2.64 416.0 9.92
我决定关注.Call,看看这是如何产生的。我查看了分析文件以在调用堆栈中找到那些带有.Call 的条目,以下是调用堆栈中的顶部条目(按出现次数计数):
13640 "eval"
11252 "["
7044 "standardGeneric"
4691 "<Anonymous>"
4658 "tryCatch"
4654 "tryCatchList"
4652 "tryCatchOne"
4648 "doTryCatch"
这个列表一清二楚:我有<Anonymous> 和standardGeneric。
我相信这是由于调用了 Matrix 包中的函数,但那是因为我正在查看代码,而该包似乎是唯一可能的 C 代码来源。但是,这个包中调用了很多来自 Matrix 的不同函数,而且这次似乎很难确定 哪个 函数正在消耗。
所以,我的问题是非常基本的:是否有某种方法可以以其他方式破译和归因这些调用(例如.Call、<Anonymous> 等)?考虑到所涉及的函数数,此代码的调用图绘制起来相当棘手。
我看到的后备策略是 (1) 注释掉代码位(并修改代码以使其与此一起工作)以查看时间消耗发生在哪里,或者 (2) 将某些操作包装在其他操作中函数并查看这些函数何时出现在调用堆栈上。后者是不优雅的,但它似乎是向调用堆栈添加标签的最佳方式。前者令人不快,因为运行代码需要相当长的时间,并且反复取消注释代码并重新运行令人不快。
【问题讨论】: