从文本文件中读取〜5x10 ^ 6个数字值在我的机器上相对较慢(几秒钟,我读了几个这样的文件),即使有scan(..., what="numeric", nmax=5000)或类似的技巧.尝试Rcpp这种任务的包装器是否值得(例如,Armadillo有一些实用程序来读取文本文件)?或者,由于预期的接口开销,我是否会浪费我的时间在性能上几乎没有收获?我不确定目前限制速度的是什么(内在的机器性能,或者其他?)这是我每天重复多次的任务,通常,文件格式总是相同的,1000列,大约5000行.
如果需要,这是一个要播放的示例文件.
nr <- 5000
nc <- 1000
m <- matrix(round(rnorm(nr*nc),3),nr=nr)
cat(m[1, -1], "\n", file = "test.txt") # first line is shorter
write.table(m[-1, ], file = "test.txt", append=TRUE,
row.names = FALSE, col.names = FALSE)
Run Code Online (Sandbox Code Playgroud)
更新:我尝试过read.csv.sql并load("test.txt", arma::raw_ascii)使用Armadillo,两者都比scan解决方案慢.
小智 5
请记住,我不是R专家,但也许这个概念也适用于此:通常阅读二进制文件比阅读文本文件要快得多.如果您的源文件不经常更改(例如,您在相同的数据上运行不同版本的脚本/程序),请尝试通过scan()一次读取它们并以二进制格式存储它们(手册中有一章说明导出二进制文件).从那以后,您可以修改程序以读取二进制输入.
@Rcpp:scan()和朋友可能会调用本机实现(如fscanf()),因此通过Rcpp编写自己的文件读取函数可能无法提供巨大的性能提升.您仍然可以尝试(并针对您的特定数据进行优化).
致敬巴蒂斯特,
数据输入/输出是一个巨大的话题,大到 R 自带关于数据输入/输出的手册。
R 的基本函数可能很慢,因为它们非常通用。如果您知道自己的格式,就可以轻松地为自己编写一个更快的导入适配器。如果您也知道自己的维度,那就更容易了,因为您只需要一个内存分配。
编辑: 作为第一个近似值,我会写一个 C++ 十行。打开一个文件,读取一行,将其分成标记,分配给 avector<vector< double > >或类似的东西。即使您push_back()在单个矢量元素上使用,您也应该与scan(), methinks竞争。
我曾经有一个csv reader基于 Brian Kernighan 自己的代码的 C++ 小类。相当通用(对于 csv 文件),相当强大。
然后,您可以根据需要挤压性能。
进一步编辑:这个SO 问题有许多关于 csv 阅读案例的指针,以及对 Kernighan 和 Plauger 书的引用。