输入数据每增加 10 倍,函数的持续时间就会增加 100 倍

问题描述 投票:0回答:1

我使用

sapply()
编写了一个简单的函数来定义日期向量的水年(10 月 1 日 - 9 月 30 日)。它工作得很好,只是提供的向量长度每增加 10 倍,该函数需要的时间就会延长 100 倍,这使得它无法处理大型日期向量(我需要将其应用于 300k 日期)。我的理解是 apply 系列函数是矢量化的,应该是处理大型数据集的有效方法。我在这里缺少什么?我可以使它更有效吗?

wateryear <- function(dates){
  y <- year(dates)
  m <- month(dates)
  sapply(m, function(x) {ifelse(x <= 9, paste0(y-1,"-",y), paste0(y, "-", y+1))})
}
d<-c("2020/01/01")
system.time(wateryear(rep(d,100))) # 0.008
system.time(wateryear(rep(d,1000))) # 0.651
system.time(wateryear(rep(d,10000))) # 63.854
r function performance apply sapply
1个回答
0
投票

我不知道为什么 sapply 这么慢,但是当 n = 1000 时,运行速度快 300 倍,当 n = 5000 时,运行速度快 100 倍。

library(lubridate)
wateryear2 <- function(dates){
  d <- ymd(dates)
  m <- month(d)
  y <- year(d) + (m > 9)
  paste(y-1, y, sep = "-")
}

bench::mark(
  wateryear(rep(d,1000)),
  wateryear2(rep(d,1000))
)


# A tibble: 2 × 13
  expression                    min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time result        memory                 time       gc      
  <bch:expr>               <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm> <list>        <list>                 <list>     <list>  
1 wateryear(rep(d, 1000))     968ms    968ms      1.03      32MB     0        1     0      968ms <chr [1,000]> <Rprofmem [4,296 × 3]> <bench_tm> <tibble>
2 wateryear2(rep(d, 1000))   3.04ms   3.09ms    322.       711KB     6.23   155     3      482ms <chr [1,000]> <Rprofmem [380 × 3]>   <bench_tm> <tibble>
© www.soinside.com 2019 - 2024. All rights reserved.