Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用STL将大型STL向量写入文件的最快方法_C++_Stl - Fatal编程技术网

C++ 使用STL将大型STL向量写入文件的最快方法

C++ 使用STL将大型STL向量写入文件的最快方法,c++,stl,C++,Stl,我有一个较大的字符向量(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)

我有一个较大的字符向量(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);
向量vs; // ... 用数据填充向量 流输出文件(“nanocube.txt”,ios::out | ios::binary); ostream_迭代器oi(输出文件,'\0'); 复制(vs.开始(),vs.结束(),oi);
对于这段代码,将所有数据写入文件大约需要两分钟。实际的问题是:“我可以使用STL和如何使它更快吗?”

对于
ostream\u迭代器的构造函数,您的第二个参数有一个轻微的概念错误。如果您不需要分隔符,它应该是NULL pointer(不过,幸运的是,这将被隐式地视为空分隔符),或者应该忽略第二个参数

但是,这意味着在写入每个字符后,代码需要检查指定分隔符的指针(这可能会有点低效)

我想,如果你想使用迭代器,也许你可以试试
ostreambuf\u迭代器


其他选项可能包括使用write()方法(如果它可以处理如此大的输出,或者可能以块的形式输出),或者使用特定于操作系统的输出函数。

对其使用write方法,它毕竟在ram中,并且您有连续的内存。。最快,但以后需要灵活性?丢失内置缓冲、提示顺序i/o、丢失迭代器/实用程序的隐藏内容、避免使用boost::asio时的streambuf。

由于要写入大量数据(~1GB),您应该直接写入输出流,而不是使用输出迭代器。因为向量中的数据是连续存储的,所以这将起作用,并且应该快得多

ofstream outfile("nanocube.txt", ios::out | ios::binary);
outfile.write(&vs[0], vs.size());

因为您的数据在内存中是连续的(正如Charles所说),所以您可以使用低级I/O。在Unix或Linux上,您可以写入文件描述符。在Windows XP上,使用文件句柄。(在XP上有点棘手,但在MSDN中有很好的记录。)


XP在缓冲方面有点滑稽。如果将1GB块写入句柄,速度将比将写入拆分为更小的传输大小(在循环中)慢。我发现256KB的写入是最有效的。一旦你写了循环,你就可以玩这个游戏,看看什么是最快的传输大小。

好的,我用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();
}
void writecutofile(常量向量&vs)
{
const unsigned int blocksize=262144;
无符号长块=距离(vs.begin()、vs.end())/blocksize;
流输出文件(“nanocube.txt”,ios::out | ios::binary);
对于(无符号长i=0;i距离(vs.begin()+位置,vs.end()))输出文件写入(&*(vs.begin()+位置),距离(vs.begin()+位置,vs.end());
else outfile.write(&*(vs.begin()+位置),blocksize);
}
输出文件。写入(“\0”,1);
outfile.close();
}

谢谢大家。

如果您有其他结构,此方法仍然有效

例如:

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));
}
typedef std::对STL_边;
向量v;
无效写入文件(常量字符*路径){
流输出文件(路径,ios::out | ios::binary);
outfile.write((const char*)&v.front(),v.size()*sizeof(STL_Edge));
}
无效读取文件(const char*path,int reservespace forentries){
ifstream infle(路径,ios::in | ios::binary);
v、 调整大小(reserveSpaceForEntries);
填充读取((char*)和v.front(),v.size()*sizeof(STL_边缘));
}

您可以尝试创建内存映射文件,然后使用memcpy将向量复制到内存映射文件,而不是通过文件i/o方法进行写入。

我刚刚阅读了Meyer的“有效STL”一节,其中提到了
[io]streambuf_迭代器
类。非常适合这个!Thnx用于校正。我是在没有深入了解的情况下从某个地方复制粘贴的。我忘了说我正在尝试使事情独立于平台,因此不存在特定于操作系统的问题,但还是thnx。在后台进行写入时,您还想做其他处理吗?如果是这样,请使用重叠I/O传递vs.data()作为缓冲区,vs.size()作为Charles Salvia指定的要写入的字节数。我想知道为什么
outfile.write(reinterpret_cast(&(vs)),vs.size()*sizeof(T))不工作?