我有一个在Linux上运行的C++应用程序,我正在优化它.如何确定代码的哪些区域运行缓慢?
我试图找到一种简单的方法来使用像R中的Perl的散列函数(基本上是缓存),因为我打算进行Perl风格的散列并编写我自己的计算备忘录.然而,其他人已经打败了我,并有包装备忘.我越挖,越我发现,如memoise和R.cache,但差异不容易明确.另外,目前还不清楚如何使用Perl风格的哈希(或Python风格的词典)并编写一个自己的memoization,而不是使用hash包,这似乎不是两个memoization包的基础.
由于我无法找到有关CRAN或其他地方的信息来区分选项,或许这应该是关于SO的社区维基问题:R中的记忆和缓存有哪些选项,它们的区别是什么?
作为比较的基础,这里是我找到的选项列表.此外,在我看来,所有都依赖于散列,所以我也会注意到散列选项.密钥/值存储在某种程度上是相关的,但是会打开关于数据库系统的大量蠕虫(例如BerkeleyDB,Redis,MemcacheDB和其他许多人).
它看起来像是:
这些是R对象外部存储的基本选项.
cacher并提供一些有用功能的OmegaHat项目.pairlist,但已被弃用.)虽然我最感兴趣的是了解选项,但我有两个基本用例:
这些真的出现了,因为我正在深入研究一些slooooow代码的分析,我真的只想计算简单的字符串,看看我是否可以通过memoization加速一些计算.能够散列输入值,即使我没有记忆,也会让我看看memoization是否有帮助.
注1:可重复研究的CRAN任务视图列出了几个软件包(cacher和R.cache),但没有详细说明使用选项.
注2:为了帮助其他人查找相关代码,这里有一些关于一些作者或包的注释.一些作者使用SO.:)
我正在尝试优化一些代码,并对来自的信息感到困惑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)将某些操作包装在其他函数中并查看当这些函数出现在调用堆栈上时.后者是不优雅的,但似乎这是向调用堆栈添加标记的最佳方式.前者是令人不愉快的,因为运行代码需要相当长的时间,迭代地取消注释代码并重新运行是令人不快的.