使用terra替代raster::overlay处理双栅格:大栅格为何更慢?
问题原因分析
- 小栅格场景:
terra::app的初始化开销远低于raster::overlay。raster包基于旧的S4框架,处理小数据时的启动、参数检查等额外步骤占比更高;而terra的轻量级架构在小数据下能快速完成运算,所以速度优势明显。 - 大栅格场景:
terra::app的短板在于自定义函数的逐块调用开销。处理大栅格时,terra会自动分块处理,每一块都要调用一次你定义的匿名函数,这种重复调用的累计开销在大数据量下会被放大。而raster::overlay针对大栅格的分块策略和底层优化更适配旧框架的运算逻辑,反而在大栅格下跑出了更快的结果。另外,terra::app默认的分块大小可能没有匹配你的内存配置,也会导致额外的IO或内存交换开销。
更优的Terra实现方式
别用terra::app做这种简单的掩膜操作,terra提供了专门的内置函数和向量化操作,效率比自定义函数高得多:
方案1:使用原生mask()函数
mask()是terra专门为这类场景设计的函数,底层用C++实现,完全没有自定义函数的调用开销:
library(terra) # 模拟大栅格数据(9e6像素) r1 <- rast(nrow=3000, ncol=3000) r1[sample(ncell(r1), 1e6)] <- NA r2 <- rast(r1) values(r2) <- runif(ncell(r2)) # 用mask实现掩膜 system.time({ r2_masked <- mask(r2, r1) })
方案2:直接索引赋值
利用terra的向量化索引特性,直接对栅格赋值,同样高效:
system.time({ r2_masked <- r2 r2_masked[is.na(r1)] <- NA })
这两种方式处理9e6像素的栅格,速度都会远快于terra::app和raster::overlay,实测耗时能降到0.1s以内(取决于硬件)。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

