C++ 从磁盘写入和读取性能
C++ Performance writing and reading from disk
可能的重复项:
以C++非常快的速度编写二进制文件
我在内存中有大量无符号的 32 位整数(15 亿个条目)。我需要将它们写入文件并将它们读回主内存。
现在,我使用:
ofstream ofs;
ofs.open(filename);
for (uint64_t i = 0 ; i < 1470000000 ; i++)
ofs << integers << " " ;
和
ifstream ifs;
ifs.open(filename);
for (uint64_t i = 0 ; i < 1470000000 ; i++)
ifs >> integers ;
这需要几分钟才能执行。任何人都可以帮助我,有没有库方法可以更快地做到这一点?或者任何建议,以便我可以运行性能测试?谁能给我看一些简单的C++代码,这些代码使用mmap
来执行上述操作(在 Linux 上)?
编辑:示例案例
#include<iostream>
#include <stdint.h>
#include <cstdio>
#include <cstdlib>
#include <sstream>
using namespace std;
main()
{
uint32_t* ele = new uint32_t [100] ;
for(int i = 0; i < 100 ; i++ )
ele[i] = i ;
for(int i = 0; i < 100 ; i++ ){
if(ele[i] < 20)
continue ;
else
// write ele[i] to file
;
}
for(int i = 0; i < 100 ; i++ ){
if(ele[i] < 20)
continue ;
else
// read number from file
// ele[i] = number * 10 ;
;
}
std::cin.get();
}
首先要做的是确定时间的去向。格式化和解析文本并非易事,可能需要一些时间,但实际的写作和阅读也可以,考虑到大小的文件。 第二件事是确定如何"便携"数据必须是:最快的解决方案几乎可以肯定是 mmap
(或其 Windows 等效项)将数组转换为文件直接,从不读写。 这不提供然而,便携式表示,甚至升级编译器可能会使数据不可读。 (对于 32 位不太可能今天的整数,但过去也发生过)。
一般来说,如果时间要用于阅读和写作,你将想使用mmap
进行调查。 如果它要格式化和解析,您将需要调查某种排序二进制格式 - 这也有助于读取和写入如果它使生成的文件更小。 最简单的二进制文件格式,使用正常网络标准写入值,要求不超过:
void
writeInt( std::ostream& dest, int32_t integer )
{
dest.put( (integer >> 24) & 0xFF );
dest.put( (integer >> 16) & 0xFF );
dest.put( (integer >> 8) & 0xFF );
dest.put( (integer ) & 0xFF );
}
int32_t
readInt( std::istream& source )
{
int32_t results = 0;
results = source.get() << 24;
results |= source.get() << 16;
results |= source.get() << 8;
results |= source.get();
return results;
}
(显然需要添加一些错误检查。
如果许多整数实际上很小,您可以尝试一些可变长度编码,例如谷歌协议中使用的编码缓冲区。 如果大多数整数都在 -64...63 范围内,这可能会导致文件只有四分之一的大小(这再次,将改善读写所需的时间)。
如果你知道大小,只需写/写一个数组。
通过对输入和输出流使用更大的缓冲区,可能会获得更好的性能:
ofstream ofs;
char * obuffer = new char[bufferSize];
ofs.rdbuf ()->pubsetbuf (obuffer, bufferSize);
ofs.open (filename);
ifstream ifs;
char * ibuffer = new char[bufferSize];
ifs.rdbuf ()->pubsetbuf (ibuffer, bufferSize);
ifs.open (filename);
此外ifs >> integers ;
解析整数的相当慢的方法。尝试读取行,然后使用std::strtol()
来解析它们。IME,它的速度要快得多。
如果您只想复制,则可以使用它来提高性能:
std::ifstream input("input");
std::ofstream output("ouptut");
output << input.rdbuf();
或者设置缓冲区大小可能会提高速度:
char cbuf[buf_size];
ifstream fin;
fin.rdbuf()->pubsetbuf(cbuf,buf_size);
我没有在我的答案中考虑长 int 问题,因为我根本不知道为什么它们会影响流性能,但我希望它无论如何都会有所帮助.
- 理解boost::asio-async_read在无需读取内容时的行为
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 使用新行和不使用新行读取文件
- 读取文件并输入到矢量中
- 与普通变量相比,仅仅读取原子变量的性能有什么不同吗
- 多个 OpenMP 线程读取(而不是写入)共享变量的性能成本?
- 在C 中读取大型CSV文件性能问题
- Linux 与 Windows,C++读取 CSV 文件的运行时性能差异
- C和C++文件读取性能的比较
- 在Windows上读取性能数据计数器是否需要任何特殊的安全权限
- 从文件中读取大量数据并以有效的方式解析日期.如何提高海量数据的性能
- 从标准输出读取奇怪的性能问题
- 是否有可能通过使用openMP在fstream(文件读取)上获得一些性能提升
- 堆与读取Map最左边节点的相对性能
- 读取二进制文件的性能
- 如何在读取文件时获得更高的性能
- 逐行读取文件与读取整个文件时的性能
- c++文本文件读取性能
- 如何在C++中读取性能计数器
- C++ 从磁盘写入和读取性能