【发布时间】:2011-04-08 17:30:04
【问题描述】:
我想知道是否可以通过类似于matlab 的 Profiler 的方式从 R-Code 获取配置文件。也就是说,要知道哪些行号是特别慢的。
到目前为止,我所取得的成绩并不令人满意。我使用Rprof 为我制作了个人资料文件。使用 summaryRprof 我得到如下内容:
$by.self self.time self.pct total.time total.pct [.data.frame 0.72 10.1 1.84 25.8 inherits 0.50 7.0 1.10 15.4 data.frame 0.48 6.7 4.86 68.3 unique.default 0.44 6.2 0.48 6.7 deparse 0.36 5.1 1.18 16.6 rbind 0.30 4.2 2.22 31.2 match 0.28 3.9 1.38 19.4 [<-.factor 0.28 3.9 0.56 7.9 levels 0.26 3.7 0.34 4.8 NextMethod 0.22 3.1 0.82 11.5 ...
和
$by.total total.time total.pct self.time self.pct data.frame 4.86 68.3 0.48 6.7 rbind 2.22 31.2 0.30 4.2 do.call 2.22 31.2 0.00 0.0 [ 1.98 27.8 0.16 2.2 [.data.frame 1.84 25.8 0.72 10.1 match 1.38 19.4 0.28 3.9 %in% 1.26 17.7 0.14 2.0 is.factor 1.20 16.9 0.10 1.4 deparse 1.18 16.6 0.36 5.1 ...
说实话,从这个输出中我没有找到我的瓶颈在哪里,因为 (a) 我经常使用 data.frame 并且 (b) 我从不使用例如 deparse。还有,[是什么?
所以我尝试了 Hadley Wickham 的 profr,但考虑到下图,它不再有用了:
有没有更方便的方法来查看哪些行号和特定的函数调用很慢?
或者,我应该查阅一些文献吗?
任何提示表示赞赏。
编辑 1:
根据 Hadley 的评论,我将在下面粘贴我的脚本代码和该图的基本图版本。但请注意,我的问题与此特定脚本无关。这只是我最近写的一个随机脚本。 我正在寻找一种通用的方法来找出瓶颈并加速R-code。
数据 (x) 如下所示:
type word response N Classification classN Abstract ANGER bitter 1 3a 3a Abstract ANGER control 1 1a 1a Abstract ANGER father 1 3a 3a Abstract ANGER flushed 1 3a 3a Abstract ANGER fury 1 1c 1c Abstract ANGER hat 1 3a 3a Abstract ANGER help 1 3a 3a Abstract ANGER mad 13 3a 3a Abstract ANGER management 2 1a 1a ... until row 1700
脚本(带有简短的解释)是这样的:
Rprof("profile1.out") # A new dataset is produced with each line of x contained x$N times y <- vector('list',length(x[,1])) for (i in 1:length(x[,1])) { y[[i]] <- data.frame(rep(x[i,1],x[i,"N"]),rep(x[i,2],x[i,"N"]),rep(x[i,3],x[i,"N"]),rep(x[i,4],x[i,"N"]),rep(x[i,5],x[i,"N"]),rep(x[i,6],x[i,"N"])) } all <- do.call('rbind',y) colnames(all) <- colnames(x) # create a dataframe out of a word x class table table_all <- table(all$word,all$classN) dataf.all <- as.data.frame(table_all[,1:length(table_all[1,])]) dataf.all$words <- as.factor(rownames(dataf.all)) dataf.all$type <- "no" # get type of the word. words <- levels(dataf.all$words) for (i in 1:length(words)) { dataf.all$type[i] <- as.character(all[pmatch(words[i],all$word),"type"]) } dataf.all$type <- as.factor(dataf.all$type) dataf.all$typeN <- as.numeric(dataf.all$type) # aggregate response categories dataf.all$c1 <- apply(dataf.all[,c("1a","1b","1c","1d","1e","1f")],1,sum) dataf.all$c2 <- apply(dataf.all[,c("2a","2b","2c")],1,sum) dataf.all$c3 <- apply(dataf.all[,c("3a","3b")],1,sum) Rprof(NULL) library(profr) ggplot.profr(parse_rprof("profile1.out"))
最终数据如下所示:
1a 1b 1c 1d 1e 1f 2a 2b 2c 3a 3b pa words type typeN c1 c2 c3 pa 3 0 8 0 0 0 0 0 0 24 0 0 ANGER Abstract 1 11 0 24 0 6 0 4 0 1 0 0 11 0 13 0 0 ANXIETY Abstract 1 11 11 13 0 2 11 1 0 0 0 0 4 0 17 0 0 ATTITUDE Abstract 1 14 4 17 0 9 18 0 0 0 0 0 0 0 0 8 0 BARREL Concrete 2 27 0 8 0 0 1 18 0 0 0 0 4 0 12 0 0 BELIEF Abstract 1 19 4 12 0
基础图表:
【问题讨论】:
-
您可以尝试使用
plot代替ggplot与profr 吗?查看您的原始代码也很有用。 -
我已经厌倦了指出这一点。基于与 gprof 中相同想法的分析器具有相同的错误。所有这些关于自我时间、函数而不是线、图形和一般测量的业务,都是相同的过热无用的概念。有一些简单的方法:*.com/questions/1777556/alternatives-to-gprof/…
-
@hadely:查看我的编辑。 @Mike:我发现问题而不是衡量某事。基本上不相关的是你的观点。听起来和我要找的完全一样。但这是否在 R 中的某个地方实现?
-
@Henrik:刚刚有人给了我一票,把我的注意力带回到这里。事实上,我使用了 Rprof,但只是为了(以大间隔)取样,而不是“分析”它们。样本最终保存在一个文件中,我只是查看它们。尽管它们不包含行号信息,但它们可以工作。如果函数 A 在两个地方调用函数 B,我会改为让 A 调用 B1 和 B2,而那些人调用 B。这样我就可以知道调用来自 A 中的哪个位置。 Kludgy,但它完成了工作。