R 最佳实践:对于 CRAN,您应该优化还是保留基本方法
R best practices : for CRAN, should you optimize or keep the base methods
我在CRAN上写我的包,在优化速度的路上
我发现了一个主要问题,即时间序列的“基本”(实际上是统计数据)方法非常慢,尤其是当您使用相同的 tsp 时。
set.seed(1)
a <- ts(rnorm(480),start=2010,freq=12)
b <- ts(rnorm(480),start=2010,freq=12)
library(microbenchmark)
ts_fastop <- function(x,y,FUN) {
FUN <- match.fun(FUN)
tspx <- tsp(x)
if (any(abs(tspx - tsp(y)) > getOption("ts.eps"))) stop("This method is only made for similar tsp", call. = FALSE)
ts(FUN(as.numeric(x),as.numeric(y)),start=tspx[1L],frequency = tspx[3L])
}
identical(ts_fastop(a,b,`+`),a+b)
# [1] TRUE
microbenchmark(ts_fastop(a,b,`+`),a+b,times=1000L)
# Unit: microseconds
# expr min lq mean median uq max neval
# ts_fastop(a, b, `+`) 13.7 15.3 24.1260 17.4 18.9 6666.4 1000
# a + b 364.5 372.5 385.7744 375.6 380.4 7218.4 1000
我认为 380 微秒对于几个变量的简单 +
来说太多了。
但是,当我简化这些方法时,我想知道最佳实践是什么:
- 如果有人快捷方式主要功能,我想这会使 R 核心团队管理升级变得不那么容易
- 源码写成a+b比ts_fastop(a,b,
+
) 的可读性更好
那么对此有什么建议吗?
谢谢
定义 ts
的子类,在这种情况下两者可以共存。这应该适用于从 ts
对象、普通向量、zoo
和 xts
对象以及存在 as.ts
方法的其他对象构建 fast_ts
对象。
as.fast_ts <- function(x, ...) UseMethod("as.fast_ts")
as.fast_ts.fast_ts <- identity
as.fact_ts.default <- function(x, ...) structure(as.ts(x, ...),
class = c("fast_ts", "ts"))
Ops.fast_ts <- function(e1, e2) {
result <- match.fun(.Generic)(c(e1), c(e2))
structure(result, tsp = tsp(e1), class = c("fast_ts", "ts"))
}
# test
set.seed(1)
a <- ts(rnorm(480),start=2010,freq=12)
b <- ts(rnorm(480),start=2010,freq=12)
af <- as.fast_ts(a)
bf <- as.fast_ts(b)
library(microbenchmark)
microbenchmark(a+b, af+bf)
我在CRAN上写我的包,在优化速度的路上
我发现了一个主要问题,即时间序列的“基本”(实际上是统计数据)方法非常慢,尤其是当您使用相同的 tsp 时。
set.seed(1)
a <- ts(rnorm(480),start=2010,freq=12)
b <- ts(rnorm(480),start=2010,freq=12)
library(microbenchmark)
ts_fastop <- function(x,y,FUN) {
FUN <- match.fun(FUN)
tspx <- tsp(x)
if (any(abs(tspx - tsp(y)) > getOption("ts.eps"))) stop("This method is only made for similar tsp", call. = FALSE)
ts(FUN(as.numeric(x),as.numeric(y)),start=tspx[1L],frequency = tspx[3L])
}
identical(ts_fastop(a,b,`+`),a+b)
# [1] TRUE
microbenchmark(ts_fastop(a,b,`+`),a+b,times=1000L)
# Unit: microseconds
# expr min lq mean median uq max neval
# ts_fastop(a, b, `+`) 13.7 15.3 24.1260 17.4 18.9 6666.4 1000
# a + b 364.5 372.5 385.7744 375.6 380.4 7218.4 1000
我认为 380 微秒对于几个变量的简单 +
来说太多了。
但是,当我简化这些方法时,我想知道最佳实践是什么:
- 如果有人快捷方式主要功能,我想这会使 R 核心团队管理升级变得不那么容易
- 源码写成a+b比ts_fastop(a,b,
+
) 的可读性更好
那么对此有什么建议吗?
谢谢
定义 ts
的子类,在这种情况下两者可以共存。这应该适用于从 ts
对象、普通向量、zoo
和 xts
对象以及存在 as.ts
方法的其他对象构建 fast_ts
对象。
as.fast_ts <- function(x, ...) UseMethod("as.fast_ts")
as.fast_ts.fast_ts <- identity
as.fact_ts.default <- function(x, ...) structure(as.ts(x, ...),
class = c("fast_ts", "ts"))
Ops.fast_ts <- function(e1, e2) {
result <- match.fun(.Generic)(c(e1), c(e2))
structure(result, tsp = tsp(e1), class = c("fast_ts", "ts"))
}
# test
set.seed(1)
a <- ts(rnorm(480),start=2010,freq=12)
b <- ts(rnorm(480),start=2010,freq=12)
af <- as.fast_ts(a)
bf <- as.fast_ts(b)
library(microbenchmark)
microbenchmark(a+b, af+bf)