Programing

R에서 캐싱 / 메모 화 / 해싱 옵션

lottogame 2020. 11. 6. 07:47
반응형

R에서 캐싱 / 메모 화 / 해싱 옵션


Perl 스타일의 해싱을 수행하고 계산에 대한 메모를 작성하려고했기 때문에 R (본질적으로 캐싱)에서 Perl의 해시 함수와 같은 것을 사용하는 간단한 방법을 찾으려고합니다. 그러나 다른 사람들은 나를 펀치로 이기고 메모 패키지를 가지고 있습니다. 더 많이 발굴할수록 더 많이 찾을 수 있습니다 (예 : memoiseR.cache). 그러나 차이점은 쉽게 명확하지 않습니다. 또한, 어떻게 다른 사람이 Perl 스타일 해시 (또는 Python 스타일 사전)를 얻고 자신의 메모를 작성할 수 hash있는지, 두 메모 패키지를 뒷받침하지 않는 패키지 를 사용하는 것 외에는 명확 하지 않습니다.

옵션을 구별하기 위해 CRAN 또는 다른 곳에서 정보를 찾을 수 없기 때문에 아마도 이것은 SO에 대한 커뮤니티 위키 질문이어야합니다. R에서 메모 화 및 캐싱 옵션은 무엇이며 차이점은 무엇입니까?


비교를위한 기준으로 내가 찾은 옵션 목록은 다음과 같습니다. 또한 모든 것이 해싱에 의존하는 것처럼 보이므로 해싱 옵션도 주목할 것입니다. 키 / 값 스토리지는 다소 관련이 있지만 DB 시스템 (예 : BerkeleyDB, Redis, MemcacheDB 및 기타 여러 웜)과 관련하여 엄청난 수의 웜을 엽니 다 .

옵션은 다음과 같습니다.

해싱

  • digest- 임의의 R 객체에 대한 해싱을 제공합니다.

메모 화

  • 메모 -기능 메모를위한 매우 간단한 도구입니다.
  • R.cache- 일부 기능에 예제가없는 것처럼 보이지만 메모를위한 더 많은 기능을 제공합니다.

캐싱

  • hash -Perl의 해시 및 Python 사전과 유사한 캐싱 기능을 제공합니다.

키 / 값 저장소

R 개체의 외부 저장소에 대한 기본 옵션입니다.

체크 포인트

다른

  • Base R은 명명 된 벡터 및 목록, 데이터 프레임의 행 및 열 이름, 환경의 항목 이름을 지원합니다. 목록을 사용하는 것은 약간의 곤경에 처한 것 같습니다. (도 pairlist있지만 더 이상 사용되지 않습니다 .)
  • data.table 패키지는 데이터 테이블에있는 요소의 빠른 검색을 지원합니다.

사용 사례

주로 옵션을 아는 데 관심이 있지만 두 가지 기본 사용 사례가 발생합니다.

  1. 캐싱 : 간단한 문자열 계산. [참고 : 이것은 NLP 용이 아니지만 일반적인 용도이므로 NLP 라이브러리는 과잉입니다. 전체 문자열 집합이 메모리에로드 될 때까지 기다리지 않는 것을 선호하기 때문에 테이블은 부적절합니다. Perl 스타일 해시는 적절한 수준의 유틸리티입니다.]
  2. 괴물 같은 계산의 기억.

이러한 문제는 제가 slooooow 코드의 프로파일 링을 파헤 치고 있고, 단순한 문자열을 세고 메모 화를 통해 계산 속도를 높일 수 있는지 확인하고 싶기 때문에 발생합니다 . 내가 메모하지 않더라도 입력 값을 해시 할 수 있으면 메모가 도움이 될 수 있는지 확인할 수 있습니다.


참고 1 : Reproducible ResearchCRAN 작업보기 에는 몇 가지 패키지 ( cacherR.cache)가 나열되어 있지만 사용 옵션에 대한 자세한 설명은 없습니다.

참고 2 : 관련 코드를 찾는 다른 사용자를 돕기 위해 여기에 일부 작성자 또는 패키지에 대한 몇 가지 참고 사항이 있습니다. 저자 중 일부는 SO를 사용합니다. :)

  • Dirk Eddelbuettel : digest-다른 많은 패키지가 이것에 의존합니다.
  • 로저 펭 : cacher, filehash, stashR- 다른 방법으로이 주소를 다른 문제; 참조 로저의 사이트를 더 패키지.
  • Christopher Brown : hash-유용한 패키지 인 것 같지만 ODG에 대한 링크가 다운되었습니다.
  • Henrik Bengtsson : R.cache& Hadley Wickham : memoise-한 패키지를 다른 패키지보다 선호하는시기는 아직 명확하지 않습니다.

참고 3 : 어떤 사람들은 메모 / 기억을 사용하고 다른 사람들은 메모 / 기억을 사용합니다. 주변을 검색하는 경우 메모를 남겨주세요. 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)

내가 시도한 패키지의 일부 기능에 문제를 memoise주었기 때문에 운이 좋지 않았습니다 too deep recursive. R.cacheI 더 좋은 행운이 있었다. 다음은 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 ...)

@biocyperman 솔루션과 관련이 있습니다 . R.cache에는 캐시의로드, 저장 및 평가를 방지하는 래핑 기능이 있습니다. 수정 된 기능을 참조하십시오.

R.cache는로드, 평가, 저장을위한 래퍼를 제공합니다. 다음과 같이 코드를 단순화 할 수 있습니다.

simulate <- function(mean, sd) {
key <- list(mean, sd)
data <- evalWithMemoization(key = key, expr = {
    cat("Generating data from scratch...")
    data <- rnorm(1000, mean=mean, sd=sd)
    Sys.sleep(1) # Emulate slow algorithm
    cat("ok\n")
    data})
}

참고 URL : https://stackoverflow.com/questions/7262485/options-for-caching-memoization-hashing-in-r

반응형