【发布时间】:2019-07-25 15:32:43
【问题描述】:
我决定将我的代码从 dplyr 重写为 data.table,因为我听说它更快。
令人惊讶的是,我设法在执行时间上只获得了微不足道的加速。是我的数据太小还是我写的 data.table 风格很糟糕?
除了输出的类之外,结果是相同的。
我没有故意使用 setDT(),因为它是主观的。
编辑:我做了一个类似的可重现的例子。
pacman::p_load(gapminder, data.table, dplyr, stringr, microbenchmark)
gapminder -> gapminder
as_tibble(gapminder) -> gapminder_tibble
as.data.table(gapminder) -> gapminder_data.table
microbenchmark(
dplyr = {
gapminder_tibble %>%
filter(year > 1900, year < 1990) %>%
mutate(country = str_sub(str_to_lower(country), 5)) %>%
count(country)
},
data.table = {
gapminder_data.table[year > 1900 & year < 1990][, country := str_sub(str_to_lower(country), 5)][, .(n = .N), by = country]
},
times = 1000
)
Data.table 代码更慢...
Unit: milliseconds
expr min lq mean median uq max neval cld
dplyr 2.441601 2.756801 3.165089 2.965350 3.181802 29.1171 1000 a
data.table 2.646601 3.101201 3.548372 3.383252 3.661500 11.9474 1000 b
这是为什么呢?如何让它更快?有什么建议吗?在data.table中最快的写法是什么?
【问题讨论】:
-
你可以
setkey让它运行得更快一点 -
很大程度上取决于您执行此操作的行数。我通常使用超过 100.000 行的 data.table。当处理 1.000.000 及更多时,差异非常显着。在您的情况下,尤其是 mutate 和 group_by (在计数内)应该在 data.table 中表现更好。
-
当您执行基准测试时,请确保您将苹果与苹果进行比较。目前,您在每次迭代中都使用
as.data.table,这会导致一些(轻微但可能不是微不足道的)开销。比较应该只是核心问题,在微基准测试之前完成了任何up front and only once工作。 -
如果您制作了一个可重现的示例,将会很有用。
-
3 毫秒已经如此之快,以至于此示例无法说明需要提高速度的情况。不过,通常使用较大的数据和某些操作会有一些好处。
标签: r performance dplyr data.table