我有一个大的矢量(10 ^ 9个元素)的字符,我想知道将这样的矢量写入文件的最快方法是什么。到目前为止,我一直在使用下一个代码:
vector<char> vs;
// ... Fill vector with data
ofstream outfile("nanocube.txt", ios::out | ios::binary);
ostream_iterator<char> oi(outfile, '\0');
copy(vs.begin(), vs.end(), oi);
对于此代码,将所有数据写入文件大约需要两分钟。实际问题是:“我可以使用STL加快速度吗?”
答案 0 :(得分:23)
要写入如此大量的数据(~1GB),您应该直接写入输出流,而不是使用输出迭代器。由于向量中的数据是连续存储的,因此这将起作用并且应该更快。
ofstream outfile("nanocube.txt", ios::out | ios::binary);
outfile.write(&vs[0], vs.size());
答案 1 :(得分:3)
ostream_iterator
的构造函数的第二个参数存在轻微的概念错误。它应该是NULL指针,如果你不想要一个分隔符(虽然,幸运的是,这将被隐含地对待),或者第二个参数应该被省略。
但是,这意味着在写完每个字符后,代码需要检查指定分隔符的指针(这可能有点效率低)。
我认为,如果你想使用迭代器,也许你可以试试ostreambuf_iterator
。
其他选项可能包括使用write()方法(如果它可以处理这么大的输出,或者可能以块的形式输出),也许还包括特定于OS的输出函数。
答案 2 :(得分:2)
由于您的数据在内存中是连续的(正如Charles所说),您可以使用低级I / O.在Unix或Linux上,您可以写入文件描述符。在Windows XP上,使用文件句柄。 (这在XP上有点棘手,但在MSDN中有详细记载。)
XP缓冲有点搞笑。如果将1GB块写入句柄,则会比将写入分成较小的传输大小(在循环中)慢。我发现256KB写入效率最高。一旦你编写了循环,你可以玩这个,看看最快的传输大小。
答案 3 :(得分:1)
好的,我用for循环写了方法实现,在每次迭代时写入256KB块(如Rob建议的)数据,结果是16秒,所以问题解决了。这是我谦虚的实现,所以请随意评论:
void writeCubeToFile(const vector<char> &vs)
{
const unsigned int blocksize = 262144;
unsigned long blocks = distance(vs.begin(), vs.end()) / blocksize;
ofstream outfile("nanocube.txt", ios::out | ios::binary);
for(unsigned long i = 0; i <= blocks; i++)
{
unsigned long position = blocksize * i;
if(blocksize > distance(vs.begin() + position, vs.end())) outfile.write(&*(vs.begin() + position), distance(vs.begin() + position, vs.end()));
else outfile.write(&*(vs.begin() + position), blocksize);
}
outfile.write("\0", 1);
outfile.close();
}
Thnx给大家。
答案 4 :(得分:1)
如果您有其他结构,此方法仍然有效。
例如:
typedef std::pair<int,int> STL_Edge;
vector<STL_Edge> v;
void write_file(const char * path){
ofstream outfile(path, ios::out | ios::binary);
outfile.write((const char *)&v.front(), v.size()*sizeof(STL_Edge));
}
void read_file(const char * path,int reserveSpaceForEntries){
ifstream infile(path, ios::in | ios::binary);
v.resize(reserveSpaceForEntries);
infile.read((char *)&v.front(), v.size()*sizeof(STL_Edge));
}
答案 5 :(得分:1)
您可以尝试创建内存映射文件,然后使用memcpy将向量复制到内存映射文件,而不是通过文件i / o方法进行写入。
答案 6 :(得分:-1)
在它上面使用write方法,它毕竟是ram并且你有很多内存..最快,同时寻找灵活性?丢失内置缓冲,提示顺序i / o,丢失迭代器/实用程序的隐藏内容,尽可能避免使用streambuf但是使用boost :: asio来弄脏...