[英]Read vector from file
我有一個長度為 6.5 億的大向量。 我希望將此向量存儲在磁盤(5 GB)上,然后將整個向量加載到內存中,以便各種功能可以快速訪問其元素。
這是我在 Rcpp 中以較小規模執行此操作的嘗試。 以下代碼只是導致我的 R 會話崩潰,沒有錯誤消息。 我究竟做錯了什么?
代碼:
output_file = file(description="test.bin",open="a+b")
writeBin(runif(10), output_file,size=8)
close(output_file)
rcpp 代碼:
#include <Rcpp.h>
#include <fstream>
using namespace Rcpp;
std::vector<double> read_vector_from_file(std::string filename)
{
std::vector<char> buffer{};
std::ifstream ifs(filename, std::ios::in | std::ifstream::binary);
std::istreambuf_iterator<char> iter(ifs);
std::istreambuf_iterator<char> end{};
std::copy(iter, end, std::back_inserter(buffer));
std::vector<double> newVector(buffer.size() / sizeof(double));
memcpy(&newVector[0], &buffer[0], buffer.size());
return newVector;
}
std::vector<double> LT = read_vector_from_file("test.bin");
// [[Rcpp::export]]
double Rcpp_test() {
return LT[3];
}
多年來,我已經為快速和骯臟的數據故事實施了幾次類似上述的方法。 這些天來,我不再推薦它,因為我們有fst和qs之類的出色軟件包,它們在這方面做得更好,具有並行化、壓縮和其他功能。
但正如你所問,答案隨之而來。 我發現文件的 C API 更簡單,更接近你在 R 中所做的。所以在這里我們只是打開並讀取 10 個大小為 8 的項目(對於double
),因為這是我們知道你寫的。 我曾經對此進行了概括,並為enum
類型和數字編寫了兩個int
值。
#include <Rcpp.h>
#include <fstream>
using namespace Rcpp;
// [[Rcpp::export]]
Rcpp::NumericVector Rcpp_test(std::string filename, size_t size) {
Rcpp::NumericVector v(size);
FILE *in = fopen(filename.c_str(), "rb");
if (in == nullptr) Rcpp::stop("Cannot open file", filename);
auto nr = fread(&v[0], sizeof(double), size, in);
if (nr != size) Rcpp::stop("Bad payload");
Rcpp::Rcout << nr << std::endl;
fclose(in);
return v;
}
/*** R
set.seed(123)
rv <- runif(10)
filename <- "test.bin"
if (!file.exists(filename)) {
output_file <- file(description="test.bin",open="a+b")
writeBin(rv, output_file, size=8)
close(output_file)
}
nv <- Rcpp_test(filename, 10)
data.frame(rv, nv)
all.equal(rv,nv)
*/
通過修復種子並比較寫入和讀取的數據,該代碼是一個輕微的概括。
> Rcpp::sourceCpp("answer.cpp")
> set.seed(123)
> rv <- runif(10)
> filename <- "test.bin"
> if (!file.exists(filename)) {
+ output_file <- file(description="test.bin",open="a+b")
+ writeBin(rv, output_file, size=8)
+ close(output_file .... [TRUNCATED]
> nv <- Rcpp_test(filename, 10)
10
> data.frame(rv, nv)
rv nv
1 0.2875775 0.2875775
2 0.7883051 0.7883051
3 0.4089769 0.4089769
4 0.8830174 0.8830174
5 0.9404673 0.9404673
6 0.0455565 0.0455565
7 0.5281055 0.5281055
8 0.8924190 0.8924190
9 0.5514350 0.5514350
10 0.4566147 0.4566147
> all.equal(rv,nv)
[1] TRUE
>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.