我有一个 R 脚本和一个 Pentaho (PDI) ETL 转换,用于从 SQL 数据库加载数据并执行计算。初始数据集有 128 万行 21 个变量,在 R 和 PDI 中是等效的。事实上,我最初编写了 R 代码,然后“移植”到 PDI 中的转换。
PDI 转换在 30 秒内运行(并且包括将输出写入单独的 DB 表的附加步骤)。R 脚本总共需要 45m 到 1 小时。我意识到 R 是一种脚本语言,因此是解释性的,但似乎我在这里错过了一些优化机会。
这是代码的概要:
sqlQuery()
使用from theRODBC
package (~45s)将数据从 SQL DB 读取到数据框中str_trim()
两列(~2 - 4s)split()
将数据分成分区以准备执行定量计算(单独功能)(~30m)parLapply()
使用(~15-20m)为每个数据分区并行运行计算函数将结果合并到一个结果数据帧中(~10 - 15m)
我尝试使用ddply()
而不是split()
, parLapply()
and rbind()
,但它运行了几个小时(> 3)而没有完成。我还修改了 SQL 选择语句以返回一个人工组 ID,它是基于两列的唯一对的行的密集等级,以提高性能。但它似乎没有达到预期的效果。我试过使用isplit()
and foreach() %dopar%
,但这也运行了几个小时没有结束。
PDI 转换是运行 Java 代码,这无疑比一般的 R 更快。但似乎等效的 R 脚本应该花费不超过 10 分钟(即比 PDI/Java 慢 20 倍)而不是一个小时或更长时间。
对其他优化技术有什么想法吗?
更新: 上面的第 3 步split()
,已通过使用此处建议的索引来解决Fast Alternative to split in R
更新2:我尝试使用mclapply()
而不是parLapply()
,它大致相同(~25m)。
更新 3: rbindlist()
而不是rbind()
在 2 秒内运行,这解决了第 5 步