Ite*_*tor 69 hash caching r memoization memoise
我试图找到一种简单的方法来使用像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.:)
digest
- 许多其他包依赖于此.cacher
,filehash
,stashR
-这些解决以不同的方式不同的问题; 请参阅Roger的网站了解更多套餐.hash
- 似乎是一个有用的包,但不幸的是,与ODG的链接已关闭.R.cache
&Hadley Wickham:memoise
- 现在还不清楚何时更喜欢一个包装而不是另一个包装.注3:有些人使用memoise/memoisation其他人使用memoize/memoization.如果您正在寻找,请注意.Henrik使用"z"而Hadley使用"s".
对于字符串的简单计数(而不是使用table
或类似),多集数据结构似乎很合适.该environment
对象可用于模拟此.
# Define the insert function for a multiset
msetInsert <- function(mset, s) {
if (exists(s, mset, inherits=FALSE)) {
mset[[s]] <- mset[[s]] + 1L
} else {
mset[[s]] <- 1L
}
}
# First we generate a bunch of strings
n <- 1e5L # Total number of strings
nus <- 1e3L # Number of unique strings
ustrs <- paste("Str", seq_len(nus))
set.seed(42)
strs <- sample(ustrs, n, replace=TRUE)
# Now we use an environment as our multiset
mset <- new.env(TRUE, emptyenv()) # Ensure hashing is enabled
# ...and insert the strings one by one...
for (s in strs) {
msetInsert(mset, s)
}
# Now we should have nus unique strings in the multiset
identical(nus, length(mset))
# And the names should be correct
identical(sort(ustrs), sort(names(as.list(mset))))
# ...And an example of getting the count for a specific string
mset[["Str 3"]] # "Str 3" instance count (97)
Run Code Online (Sandbox Code Playgroud)
我没有运气,memoise
因为它给too deep recursive
我试过的打包的某些功能带来了问题.随着R.cache
我有更好的运气.以下是我从R.cache
文档中修改的更加注释的代码.代码显示了执行缓存的不同选项.
# Workaround to avoid question when loading R.cache library
dir.create(path="~/.Rcache", showWarnings=F)
library("R.cache")
setCacheRootPath(path="./.Rcache") # Create .Rcache at current working dir
# In case we need the cache path, but not used in this example.
cache.root = getCacheRootPath()
simulate <- function(mean, sd) {
# 1. Try to load cached data, if already generated
key <- list(mean, sd)
data <- loadCache(key)
if (!is.null(data)) {
cat("Loaded cached data\n")
return(data);
}
# 2. If not available, generate it.
cat("Generating data from scratch...")
data <- rnorm(1000, mean=mean, sd=sd)
Sys.sleep(1) # Emulate slow algorithm
cat("ok\n")
saveCache(data, key=key, comment="simulate()")
data;
}
data <- simulate(2.3, 3.0)
data <- simulate(2.3, 3.5)
a = 2.3
b = 3.0
data <- simulate(a, b) # Will load cached data, params are checked by value
# Clean up
file.remove(findCache(key=list(2.3,3.0)))
file.remove(findCache(key=list(2.3,3.5)))
simulate2 <- function(mean, sd) {
data <- rnorm(1000, mean=mean, sd=sd)
Sys.sleep(1) # Emulate slow algorithm
cat("Done generating data from scratch\n")
data;
}
# Easy step to memoize a function
# aslo possible to resassign function name.
This would work with any functions from external packages.
mzs <- addMemoization(simulate2)
data <- mzs(2.3, 3.0)
data <- mzs(2.3, 3.5)
data <- mzs(2.3, 3.0) # Will load cached data
# aslo possible to resassign function name.
# but different memoizations of the same
# function will return the same cache result
# if input params are the same
simulate2 <- addMemoization(simulate2)
data <- simulate2(2.3, 3.0)
# If the expression being evaluated depends on
# "input" objects, then these must be be specified
# explicitly as "key" objects.
for (ii in 1:2) {
for (kk in 1:3) {
cat(sprintf("Iteration #%d:\n", kk))
res <- evalWithMemoization({
cat("Evaluating expression...")
a <- kk
Sys.sleep(1)
cat("done\n")
a
}, key=list(kk=kk))
# expressions inside 'res' are skipped on the repeated run
print(res)
# Sanity checks
stopifnot(a == kk)
# Clean up
rm(a)
} # for (kk ...)
} # for (ii ...)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11095 次 |
最近记录: |