memoise/0000755000176000001440000000000012325376322011745 5ustar ripleyusersmemoise/NAMESPACE0000644000176000001440000000024712325317016013162 0ustar ripleyusers# Generated by roxygen2 (4.0.0): do not edit by hand export(forget) export(is.memoised) export(is.memoized) export(memoise) export(memoize) importFrom(digest,digest) memoise/NEWS0000644000176000001440000000106712325317272012447 0ustar ripleyusersVersion 0.2.1 ------------------------------------------------------------------------------ * Update to fix outstanding R CMD check issues. Version 0.2 (2010-11-11) ------------------------------------------------------------------------------ NEW FEATURES * Memoised functions now have an attribute memoised=TRUE, and is.memoised() tests whether a function is memoised. (Contributed by Sietse Brouwer.) IMPROVEMENTS * Documentation is now more elaborate, and hopefully more accessible to newcomers. Thanks to Sietse Brouwer for the verbosity. memoise/R/0000755000176000001440000000000012325316640012143 5ustar ripleyusersmemoise/R/memoise.r0000644000176000001440000001137712325316640013775 0ustar ripleyusers#' \code{mf <- memoise(f)} creates \code{mf}, a memoised copy of #' \code{f}. A memoised copy is basically a #' lazier version of the same function: it saves the answers of #' new invocations, and re-uses the answers of old ones. Under the right #' circumstances, this can provide a very nice speedup indeed. #' #' There are two main ways to use the \code{memoise} function. Say that #' you wish to memoise \code{glm}, which is in the \code{stats} #' package; then you could use \cr #' \code{ mem_glm <- memoise(glm)}, or you could use\cr #' \code{ glm <- memoise(stats::glm)}. \cr #' The first form has the advantage that you still have easy access to #' both the memoised and the original function. The latter is especially #' useful to bring the benefits of memoisation to an existing block #' of R code. #' #' Two example situations where \code{memoise} could be of use: #' \itemize{ #' \item You're evaluating a function repeatedly over the rows (or #' larger chunks) of a dataset, and expect to regularly get the same #' input. #' \item You're debugging or developing something, which involves #' a lot of re-running the code. If there are a few expensive calls #' in there, memoising them can make life a lot more pleasant. #' If the code is in a script file that you're \code{source()}ing, #' take care that you don't just put \cr #' \code{ glm <- memoise(stats::glm)} \cr #' at the top of your file: that would reinitialise the memoised #' function every time the file was sourced. Wrap it in \cr #' \code{ if (!is.memoised(glm)) }, or do the memoisation call #' once at the R prompt, or put it somewhere else where it won't get #' repeated. #' } #' #' @name memoise #' @title Memoise a function. #' @param f Function of which to create a memoised copy. #' @seealso \code{\link{forget}}, \code{\link{is.memoised}}, #' \url{http://en.wikipedia.org/wiki/Memoization} #' @aliases memoise memoize #' @export memoise memoize #' @importFrom digest digest #' @examples #' # a() is evaluated anew each time. memA() is only re-evaluated #' # when you call it with a new set of parameters. #' a <- function(n) { runif(n) } #' memA <- memoise(a) #' replicate(5, a(2)) #' replicate(5, memA(2)) #' #' # Caching is done based on parameters' value, so same-name-but- #' # changed-value correctly produces two different outcomes... #' N <- 4; memA(N) #' N <- 5; memA(N) #' # ... and same-value-but-different-name correctly produces #' # the same cached outcome. #' N <- 4; memA(N) #' N2 <- 4; memA(N2) #' #' # memoise() doesn't know about default parameters. #' memB <- memoise(function(n, dummy="a") { runif(n) }) #' memB(2) #' memB(2, dummy="a") #' # It doesn't know about parameter relevance, either. #' # Different call means different cacheing, no matter #' # that the outcome is the same. #' memB(2, dummy="b") #' #' # You can create multiple memoisations of the same function, #' # and they'll be independent. #' memA(2) #' memA2 <- memoise(a) #' memA(2) # Still the same outcome #' memA2(2) # Different cache, different outcome #' #' # Don't do the same memoisation assignment twice: a brand-new #' # memoised function also means a brand-new cache, and *that* #' # you could as easily and more legibly achieve using forget(). #' # (If you're not sure whether you already memoised something, #' # use is.memoised() to check.) #' memA(2) #' memA <- memoise(a) #' memA(2) memoise <- memoize <- function(f) { cache <- new_cache() memo_f <- function(...) { hash <- digest(list(...)) if (cache$has_key(hash)) { cache$get(hash) } else { res <- f(...) cache$set(hash, res) res } } attr(memo_f, "memoised") <- TRUE return(memo_f) } #' Forget past results. #' Resets the cache of a memoised function. #' #' @param f memoised function #' @export #' @seealso \code{\link{memoise}}, \code{\link{is.memoised}} #' @examples #' memX <- memoise(function() { Sys.sleep(1); runif(1) }) #' # The forget() function #' system.time(print(memX())) #' system.time(print(memX())) #' forget(memX) #' system.time(print(memX())) forget <- function(f) { if (!is.function(f)) return(FALSE) env <- environment(f) if (!exists("cache", env, inherits = FALSE)) return(FALSE) cache <- get("cache", env) cache$reset() TRUE } #' Test whether a function is a memoised copy. #' Memoised copies of functions carry an attribute #' \code{memoised = TRUE}, which is.memoised() tests for. #' @param f Function to test. #' @seealso \code{\link{memoise}}, \code{\link{forget}} #' @export is.memoised is.memoized #' @aliases is.memoised is.memoized #' @examples #' mem_lm <- memoise(lm) #' is.memoised(lm) # FALSE #' is.memoised(mem_lm) # TRUE is.memoised <- is.memoized <- function(f) { identical(attr(f, "memoised"), TRUE) } memoise/R/cache.r0000644000176000001440000000102012325317215013361 0ustar ripleyusersnew_cache <- function() { cache <- NULL cache_reset <- function() { cache <<- new.env(TRUE, emptyenv()) } cache_set <- function(key, value) { assign(key, value, envir = cache) } cache_get <- function(key) { get(key, envir = cache, inherits = FALSE) } cache_has_key <- function(key) { exists(key, envir = cache, inherits = FALSE) } cache_reset() list( reset = cache_reset, set = cache_set, get = cache_get, has_key = cache_has_key, keys = function() ls(cache) ) } memoise/README.md0000644000176000001440000000100411470033641013211 0ustar ripleyusers# memoise If a function is called multiple times with the same input, you can often speed things up by keeping a cache of known answers that it can retrieve. This is called memoisation . The `memoise` package provides a simple syntax mf <- memoise(f) to create `mf()`, a memoised wrapper around `f()`. You can clear `mf`'s cache with forget(mf) , and you can test whether a function is memoised with is.memoised(mf) # TRUE is.memoised(f) # FALSE . memoise/MD50000644000176000001440000000070712325376322012261 0ustar ripleyusers459044d0550e18e7fdbb06ab51a20f3a *DESCRIPTION 42d91d5ce1f6db25d653397ec9da4f25 *LICENSE a191eefb459280216bf166898529f9d0 *NAMESPACE d4560c3d1ded2467aa3c5775277e1707 *NEWS 65efb37c5ec0b0aef53eba56fdbbb49f *R/cache.r f34786b305803a7a108de7099327d332 *R/memoise.r 5deda9a93204debb6e0317fdc2991231 *README.md 6e6fd030fdc60ef6aff6dee953ed1ad2 *man/forget.Rd 3081b56de525e4a4d1d7904e4a6e1e78 *man/is.memoised.Rd a2f65cec53b3f5fbeca4824ae2303ac8 *man/memoise.Rd memoise/DESCRIPTION0000644000176000001440000000107212325376322013453 0ustar ripleyusersPackage: memoise Title: Memoise functions Version: 0.2.1 Author: Hadley Wickham Maintainer: Hadley Wickham Description: Cache the results of a function so that when you call it again with the same arguments it returns the pre-computed value. URL: http://github.com/hadley/memoise BugReports: http://github.com/hadley/memoise/issues Imports: digest License: MIT + file LICENSE Roxygen: list(wrap = FALSE) Packaged: 2014-04-21 22:42:55 UTC; hadley NeedsCompilation: no Repository: CRAN Date/Publication: 2014-04-22 07:23:30 memoise/man/0000755000176000001440000000000012325317216012515 5ustar ripleyusersmemoise/man/is.memoised.Rd0000644000176000001440000000120012325317216015211 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \name{is.memoised} \alias{is.memoised} \alias{is.memoized} \title{Test whether a function is a memoised copy. Memoised copies of functions carry an attribute \code{memoised = TRUE}, which is.memoised() tests for.} \usage{ is.memoised(f) } \arguments{ \item{f}{Function to test.} } \description{ Test whether a function is a memoised copy. Memoised copies of functions carry an attribute \code{memoised = TRUE}, which is.memoised() tests for. } \examples{ mem_lm <- memoise(lm) is.memoised(lm) # FALSE is.memoised(mem_lm) # TRUE } \seealso{ \code{\link{memoise}}, \code{\link{forget}} } memoise/man/memoise.Rd0000644000176000001440000000632412325317216014447 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \name{memoise} \alias{memoise} \alias{memoize} \title{Memoise a function.} \usage{ memoise(f) } \arguments{ \item{f}{Function of which to create a memoised copy.} } \description{ \code{mf <- memoise(f)} creates \code{mf}, a memoised copy of \code{f}. A memoised copy is basically a lazier version of the same function: it saves the answers of new invocations, and re-uses the answers of old ones. Under the right circumstances, this can provide a very nice speedup indeed. } \details{ There are two main ways to use the \code{memoise} function. Say that you wish to memoise \code{glm}, which is in the \code{stats} package; then you could use \cr \code{ mem_glm <- memoise(glm)}, or you could use\cr \code{ glm <- memoise(stats::glm)}. \cr The first form has the advantage that you still have easy access to both the memoised and the original function. The latter is especially useful to bring the benefits of memoisation to an existing block of R code. Two example situations where \code{memoise} could be of use: \itemize{ \item You're evaluating a function repeatedly over the rows (or larger chunks) of a dataset, and expect to regularly get the same input. \item You're debugging or developing something, which involves a lot of re-running the code. If there are a few expensive calls in there, memoising them can make life a lot more pleasant. If the code is in a script file that you're \code{source()}ing, take care that you don't just put \cr \code{ glm <- memoise(stats::glm)} \cr at the top of your file: that would reinitialise the memoised function every time the file was sourced. Wrap it in \cr \code{ if (!is.memoised(glm)) }, or do the memoisation call once at the R prompt, or put it somewhere else where it won't get repeated. } } \examples{ # a() is evaluated anew each time. memA() is only re-evaluated # when you call it with a new set of parameters. a <- function(n) { runif(n) } memA <- memoise(a) replicate(5, a(2)) replicate(5, memA(2)) # Caching is done based on parameters' value, so same-name-but- # changed-value correctly produces two different outcomes... N <- 4; memA(N) N <- 5; memA(N) # ... and same-value-but-different-name correctly produces # the same cached outcome. N <- 4; memA(N) N2 <- 4; memA(N2) # memoise() doesn't know about default parameters. memB <- memoise(function(n, dummy="a") { runif(n) }) memB(2) memB(2, dummy="a") # It doesn't know about parameter relevance, either. # Different call means different cacheing, no matter # that the outcome is the same. memB(2, dummy="b") # You can create multiple memoisations of the same function, # and they'll be independent. memA(2) memA2 <- memoise(a) memA(2) # Still the same outcome memA2(2) # Different cache, different outcome # Don't do the same memoisation assignment twice: a brand-new # memoised function also means a brand-new cache, and *that* # you could as easily and more legibly achieve using forget(). # (If you're not sure whether you already memoised something, # use is.memoised() to check.) memA(2) memA <- memoise(a) memA(2) } \seealso{ \code{\link{forget}}, \code{\link{is.memoised}}, \url{http://en.wikipedia.org/wiki/Memoization} } memoise/man/forget.Rd0000644000176000001440000000103412325317216014270 0ustar ripleyusers% Generated by roxygen2 (4.0.0): do not edit by hand \name{forget} \alias{forget} \title{Forget past results. Resets the cache of a memoised function.} \usage{ forget(f) } \arguments{ \item{f}{memoised function} } \description{ Forget past results. Resets the cache of a memoised function. } \examples{ memX <- memoise(function() { Sys.sleep(1); runif(1) }) # The forget() function system.time(print(memX())) system.time(print(memX())) forget(memX) system.time(print(memX())) } \seealso{ \code{\link{memoise}}, \code{\link{is.memoised}} } memoise/LICENSE0000644000176000001440000000006112325317153012744 0ustar ripleyusersYEAR: 2010-2014 COPYRIGHT HOLDER: Hadley Wickham