我试图找到一种简单的方法来使用像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.:)
我看到如果我以两种不同的方式对函数使用memoise,我会得到两种不同的行为,我想了解原因.
# Non Memoised function
fib <- function(n) {
if (n < 2) return(1)
fib(n - 2) + fib(n - 1)
}
system.time(fib(23))
system.time(fib(24))
library(memoise)
# Memoisation stragagy 1
fib_fast <- memoise(function(n) {
if (n < 2) return(1)
fib_fast(n - 2) + fib_fast(n - 1)
})
system.time(fib_fast(23))
system.time(fib_fast(24))
# Memoisation strategy 2
fib_not_as_fast <- memoise(fib)
system.time(fib_not_as_fast(23))
system.time(fib_not_as_fast(24))
Run Code Online (Sandbox Code Playgroud)
策略1,真的很快,因为它重用了递归结果,而stratagy 2只有在之前看到过确切的输入时才会很快.
有人能解释一下为什么会这样吗?
我正在开发一个封装 API 调用的 R 包。为了减少实际调用的次数并加快速度,我记住了进行 API 调用的函数。为此,我创建了以下函数,它允许设置缓存目录:
memoise_fromJSON <- function(cache_dir = tempdir()) {
memoise::memoise(jsonlite::fromJSON,
cache = memoise::cache_filesystem(cache_dir))
}
Run Code Online (Sandbox Code Playgroud)
创建我使用的记忆函数
memoised_fromJSON <- memoise_fromJSON()
Run Code Online (Sandbox Code Playgroud)
现在,由于我在包中多次需要记住的函数,因此我想在包启动时记住该函数。我试过
.onLoad <- function(libname, pkgname) {
memoised_fromJSON <- my_package:::memoise_fromJSON()
}
Run Code Online (Sandbox Code Playgroud)
但我仍然需要运行memoised_fromJSON <- memoise_fromJSON()才能使其正常工作。
所以我的问题是:
我想,这些问题在某种程度上是相关的。我的理解是否正确,我的尝试.onLoad()不起作用,因为它在 的环境中创建了记忆功能.onLoad()?
PS:我知道,我无法更改cache_dir包加载,但我想设置一个合理的默认值,这样就可以轻松启动。但是,这保留了在需要时更改缓存目录的可能性。