比較 save/load, saveRDS/readRDS, feather, 與 data.table 套件的讀寫速度

最近在一些實務資料計算過程中,會產生一些比較大的 data frame,程式中也會讀/寫好幾個句型的 data frame。光是這些讀/寫的動作就佔用頗多時間。

於是我上網找了幾個相似的 R 套件/函數,主要是 .Rdata (或 rda) 格式的 save/load, .rds 格式的 saveRDS/readRDS, 以及 feather 套件的 read_feather/write_feather,結果如下。

結論是,feather 套件對於 data frame 的讀入速度最快。


後記:

後來加上 data.table 的 fread/fwrite (CSV 格式) 比較,寫出速度以 data.table 的 fwrite 最快,讀入速度還是 feather 套件的 read_feather 最快。但是 data.table 讀入後用 setDF 轉回 data-frame 時,使用 identical 函數比較與原來資料的差異,得到 FALSE.

此外,data.table 的 fread 若加上 stringsAsFactors=TRUE, 處理速度變慢,identical 結果也是 FALSE

 

docs.Rdata 檔案大小 154 MB  (49萬 403 列,40 個變數)

電腦:IBM X3650 M4
記憶體:128 GB
作業系統:Debian Linux

# dim(docs)
# [1] 490403    40

?View Code LANGUAGE
######################################
# load, save (.Rdata file)
######################################
oldt = proc.time()
load("docs")
mean(docs$scores,na.rm=T)
(proc.time()-oldt)[3]
 
# elapsed
#  33.723
 
oldt = proc.time()
save(docs,file="/tmp/docstmp.Rdata")
(proc.time()-oldt)[3]
 
# elapsed
#  39.625
 
######################################
# readRDS, saveRDS (buit-in in R)
######################################
oldt = proc.time()
docs2 = readRDS("/tmp/docs.rds")
mean(docs2$scores,na.rm=T)
(proc.time()-oldt)[3]
 
# elapsed
# 13.423
 
identical(docs2,docs)
# [1] TRUE 
 
oldt = proc.time()
saveRDS(docs,file="/tmp/docs.rds")
(proc.time()-oldt)[3]
 
# elapsed
# 39.525
 
######################################
# feather package
###################################### 
library(feather) 
 
oldt = proc.time()
docs3 = read_feather("/tmp/my_data.feather")
docs3 = as.data.frame(docs3)
mean(docs3$scores,na.rm=T)
(proc.time()-oldt)[3]
 
# elapsed
#   6.523
 
identical(docs3,docs)
# [1] TRUE
 
oldt = proc.time()
write_feather(docs,"/tmp/my_data.feather")
(proc.time()-oldt)[3]
 
# elapsed
#  11.306
 
######################################
# data.table package
###################################### 
library(data.table)
 
oldt = proc.time()
docs4 = fread("/tmp/docs4.csv")
 
# Read 490403 rows and 40 (of 40) columns from 0.417 GB file in 00:00:10
 
setDF(docs4)
mean(docs4$scores,na.rm=T)
#[1] 0.8291528
(proc.time()-oldt)[3]
 
# elapsed
#  12.651
 
identical(docs4,docs)
# [1] FALSE
 
# fread 加上 stringsAsFactors=T
 
docs5 = fread("/tmp/docs4.csv",stringsAsFactors=T)
 
# Read 490403 rows and 40 (of 40) columns from 0.417 GB file in 00:00:10
rn = rownames(docs)
setDF(docs5,rownames=rn)
mean(docs5$scores,na.rm=T)
# [1] 0.8291528
(proc.time()-oldt)[3]
 
# elapsed
# 21.826
 
identical(docs5,docs)
# [1] FALSE
 
oldt = proc.time()
fwrite(docs,file="/tmp/docs4.csv")
(proc.time()-oldt)[3]
 
# elapsed
#  2.137