# Compare the efficiency with different cores
library(s2dv)
library(multiApply)
library(rbenchmark)

# Mean along 1 dim
benchmark("apply" = {
            data <- array(rnorm(1:1000),  
                          dim = c(dat = 1, time = 12, member = 50, lon = 360, lat = 180))
            dims <- 2
            pos <- (1:length(dim(data)))[-dims]
            data <- apply(data, pos, mean, na.rm = T)
          },

          "Apply, 1 core" = {
            data <- array(rnorm(1:1000),
                          dim = c(dat = 1, time = 12, member = 50, lon = 360, lat = 180))
            dims <- 2
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 1)$output1
          },

          "Apply, 4 cores" = {
             data <- array(rnorm(1:1000),
                           dim = c(dat = 1, time = 12, member = 50, lon = 360, lat = 180))
             dims <- 2
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 4)$output1
          },
          replications = 10,
          columns = c("test", "replications", "elapsed",
                      "relative", "user.self", "sys.self"))

            test replications  elapsed relative user.self sys.self
1          apply           10  158.860    1.000   158.190    0.660
2  Apply, 1 core           10 1048.982    6.603  1048.190    0.668
3 Apply, 4 cores           10  294.800    1.856     3.037    1.368


# Mean along two dims
benchmark("apply" = {
            data <- array(rnorm(1:1000), 
                          dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2)
            pos <- (1:length(dim(data)))[-dims]
            data <- apply(data, pos, mean, na.rm = T)
          },

          "Apply, 1 core" = {
            data <- array(rnorm(1:1000),
                          dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2)
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 1)$output1

          },
          
          "Apply, 4 cores" = {
             data <- array(rnorm(1:1000),
                           dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2)
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 4)$output1

          },
          replications = 10,
          columns = c("test", "replications", "elapsed",
                      "relative", "user.self", "sys.self"))

            test replications elapsed relative user.self sys.self
1          apply           10   4.306    1.000     4.292    0.012
2  Apply, 1 core           10  22.892    5.316    22.811    0.068
3 Apply, 4 cores           10   6.380    1.482     0.085    0.264


# Mean along 4 dims
benchmark("apply" = {
            data <- array(rnorm(1:1000),
                          dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2, 3, 4)
            pos <- (1:length(dim(data)))[-dims]
            data <- apply(data, pos, mean, na.rm = T)
          },

          "Apply, 1 core" = {
            data <- array(rnorm(1:1000),
                          dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2, 3, 4)
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 1)$output1

          },

          "Apply, 4 cores" = {
             data <- array(rnorm(1:1000),
                           dim = c(dat = 1, time = 12, member = 50, lon = 30, lat = 50))
            dims <- c(1, 2, 3, 4)
            data <- Apply(list(data), target_dims = list(dims), fun = mean,
                          na.rm = T, ncores = 4)$output1

          },
          replications = 10,
          columns = c("test", "replications", "elapsed",
                      "relative", "user.self", "sys.self"))

            test replications elapsed relative user.self sys.self
1          apply           10   0.171    1.000     0.163    0.008
2  Apply, 1 core           10   0.206    1.205     0.206    0.000
3 Apply, 4 cores           10   0.424    2.480     0.054    0.264



#/////////////////// Memory profiling ////////////////////
  data <- array(rnorm(1:1000),
                dim = c(dat = 1, time = 12, member = 50, lon = 360, lat = 180))
  dims <- c(1, 2, 3, 4)

  # apply
  Rprof(memory.profiling = T)
  pos <- (1:length(dim(data)))[-dims]
  res <- apply(data, pos, mean, na.rm = T)
  Rprof(NULL)
  summaryRprof(memory = 'both')

  # Apply, 1 core
  Rprof(interval = 0.01, memory.profiling = T)
  res <- Apply(list(data), target_dims = list(dims), fun = mean,
                na.rm = T, ncores = 1)$output1
  Rprof(NULL)
  summaryRprof(memory = 'both')

  # Apply, 4 cores
  Rprof(memory.profiling = T)
  res <- Apply(list(data), target_dims = list(dims), fun = mean,
                na.rm = T, ncores = 4)$output1
  Rprof(NULL)
  summaryRprof(memory = 'both')

# Result: with 4 cores, the time is the shortest. 1 core and apply have similar time.
#         As for memory, 4 cores consumes "zero", 1 core is 1146.6 and apply is 1413.8.
    
