Skip to content

Latest commit

 

History

History
135 lines (99 loc) · 3.45 KB

File metadata and controls

135 lines (99 loc) · 3.45 KB

Caching the Mean: A Speed Test

Gauden Galea
https://github.com/ggData/ProgrammingAssignment2
15 April 2014

The first code chunk defines the two example functions provided for the assignment. This is based on the example provided by Roger Peng here

  • makeVector() receives a numeric vector and returns a modified form of that vector that is able to store the mean if once it is calculated. This version of the function is modified using the proposed changes by Patrick Gillen and modified by Lenka Vyslouzilova.
  • cachemean() takes a modified vector created as above and returns the cached mean if it is already stored. The mean will thus need to be only calculated once.
makeVector <- function(x = numeric()) {
    m <- NULL
    x <- x
    set <- function(y) {
        x <<- y
        m <<- NULL
    }
    get <- function() x
    setmean <- function(mean) m <<- mean
    getmean <- function() m
    list(set = set, get = get, setmean = setmean, getmean = getmean)
}

cachemean <- function(x, ...) {
    m <- x$getmean()
    if (!is.null(m)) {
        # message('getting cached data')
        return(m)
    }
    data <- x$get()
    m <- mean(data, ...)
    x$setmean(m)
    m
}

Two test functions are now set up:

  • test_mean(x, r) takes a numeric vector, x, and calculates its mean r times. It finally prints out the value of the mean as a check on proper functioning.
  • test_cache_mean(x,r) takes the same two arguments. It first converts the x vector into a caching object using the makeVector() function. Then it runs cachemean() on that object r times. Finally it prints out the value of cachemean() as a check on proper functioning.

These two functions should return similar results but the second should run much faster.

test_mean = function(x, r) {
    for (i in 1:r) {
        mean(x)
    }
    message(mean(x))
}

test_cache_mean = function(x, r) {
    y = makeVector(x)
    for (i in 1:r) {
        cachemean(y)
    }
    message(cachemean(y))
}

The final chunk runs both tests a large number of times and checks:

  1. the total time taken for each run
  2. whether the results of the two functions are identical
test_vec = 1:1000 * 1.35
r = 1e+06  # number of repetitions of the test

system.time(test_mean(test_vec, r))
## 675.675
##    user  system elapsed 
##   16.18    0.05   16.28
system.time(test_cache_mean(test_vec, r))
## 675.675
##    user  system elapsed 
##   2.633   0.009   2.678
identical(mean(test_vec), cachemean(makeVector(test_vec)))
## [1] TRUE

Results

Here are the results of one such run of these tests with one million iterations (they will differ to some degree from the results produced by the actual run above):

> system.time(test_mean(test_vec, r))
675.675
   user  system elapsed 
 16.470   0.042  16.573 

> system.time(test_cache_mean(test_vec, r))
675.675
   user  system elapsed 
  2.624   0.011   2.645 

> identical(mean(test_vec), cachemean(makeVector(test_vec)))
[1] TRUE

For the given vector,

  1. Both functions returned the correct, identical, value of 675.675 for the mean
  2. One million iterations of the cachemean() functions took a total of 2.645 seconds as compared to 16.573 seconds for the normal function, less than one-fifth of the time.