我有两个文件。一个文件为15 GB。另一个是684 MB。这两个文件具有相同的结构:它们由许多字符串组成,每行一个(也就是说,每个字符串由\n
分隔)。
无聊的一天,作为我的好奇新手,我决定编写一个C ++程序,将这些文件读入RAM。我在Fedora 28上使用G ++ 8.1.1编译了程序,发现当我将小文件读入RAM时,它将消耗2154 MB的RAM,而当我读大文件时,它将消耗70.2 GB的RAM。分别是原始文件大小的3.15倍和4.68倍。
为什么会这样?
这是此简单程序的源代码。我正在使用std :: vector将每一行存储为std :: string。我觉得这个问题实际上可以归结为C ++如何处理字符串?我应该考虑使用另一种数据类型吗?
#include <iostream>
#include <fstream>
#include <vector>
int main()
{
std::ifstream inFile;
std::vector<std::string> inStrings;
std::string line;
inStrings.reserve(1212356398);
inFile.open("bigfile.txt");
if (!inFile)
{
std::cerr << "Unable to open the hardcoded file" << std::endl;
exit(1);
}
while(getline(inFile, line))
{
inStrings.push_back(line);
}
std::cout << "done reading" << std::endl;
std::cin.get();
return 0;
}
答案 0 :(得分:5)
如果您尝试在学校中或作为练习来实施动态数组,请回忆分配策略,例如每次容量满时将容量增加一倍;同样,向量准备存储的量要大于实际存储的量。
同时,一个字符串本身存储一个长度,一个容量以及一个参考计数器,即使对于一个空字符串,它也至少要包含3个单词。
修改
是的,我想有关参考计数器的内容不正确。我记得这是3个字,出于某种原因,我认为它没有计算指向实际分配的内存的指针。但是我想也许仅仅是这样:指向实际字符串的指针。
无论如何,由于编译器之间的优化,实际情况有所不同。搜索“ std :: string内存分配”或类似的内容以了解更多信息。