0

我有一个程序从 .csv 读取数据并创建一个multimap. 我在下面粘贴了一个简单的版本。它工作正常,但在退出时运行速度非常慢(即,一旦程序打印出输出并到达return 0;. 我正在处理相对较大的文件,例如,从 50 到几百兆字节不等。退出时的延迟不足为奇,与文件大小成正比。

我想知道有没有什么办法可以加快退出速度?我的猜测是它很慢,因为它正在从内存中清除数据。 CTRL+c但是,在终端窗口中会立即将其关闭。我看过但没有找到太多。

#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <map>

int main (int argc, char* argv[])
{

std::string filename = "edge_data_mid.csv";

// obtain multimaps
std::ifstream fin;

fin.open(filename.c_str(), std::ios_base::in|std::ios_base::binary);
if (!fin.is_open()) {
    std::cout << "could not open the file '" << filename << "'" << std::endl;
    exit(EXIT_FAILURE);
}

std::multimap<std::string, std::string> gciting;

std::string line;

// this loop parses the file one line at a time
while (getline(fin, line)) {
    std::istringstream linestream(line);
    std::string item;

    std::string nodea;
    std::string nodeb;

    getline(linestream, item, ',');
    nodea = item;
    getline(linestream, item);
    nodeb = item;

    gciting.insert(std::pair<std::string, std::string>(nodeb, nodea));
}

fin.close();       

std::cout << gciting.count("3800035") << std::endl;

return 0;
}
4

2 回答 2

5

是的,std如果容器的析构函数管理内存(在您的情况下,它们确实管理它们包含的std::strings 的内存)并且它们包含很多元素,则它们需要一段时间。

如果您不介意内存泄漏(这不是泄漏,因为它不是连续泄漏并且是受控的),您可以动态分配映射并忘记删除它:

std::multimap<std::string, std::string>* gciting = new std::multimap<std::string, std::string>;

std::string line;

// this loop parses the file one line at a time
while (getline(fin, line)) {
    std::istringstream linestream(line);
    std::string item;

    std::string nodea;
    std::string nodeb;

    getline(linestream, item, ',');
    nodea = item;
    getline(linestream, item);
    nodeb = item;

    gciting->insert(std::pair<std::string, std::string>(nodeb, nodea));
}

fin.close();       

std::cout << gciting->count("3800035") << std::endl;

//oooops forgot to delte gciting
return 0;
}
于 2012-07-18T22:20:33.560 回答
5

我怎样才能使我的对象不被破坏?

如果您真的想阻止对象释放自身并且它包含元素(因为您知道应用程序将终止),您可以使用在堆上分配它new,然后永远不要释放内存(通常通过 完成delete)。

通常不建议这样做,但当今的主要操作系统足够智能,可以在应用程序终止时将任何分配的内存释放回操作系统,因此使用这种方法应该是安全的。


请注意,我在上面使用了“应该”而不是“”这个词。

标准中没有说分配的内存将被释放回操作系统,或者如果你不释放它会发生什么(除了你有泄漏)。

如果您正在编写要在小型系统(例如冰箱的控制器)上运行的代码,请在实际验证该平台是否确实会在终止后释放内存之前不要使用此方法。

我们不希望我们的食物变质


除了内存释放之外,它变慢的潜在原因

如果您在调试模式下运行您的应用程序,那么将发生比帮助最终调试您的应用程序所需发生的更多的事情。

尝试打开优化标志并在(通常称为)发布模式下编译它。


使用放置新..

如果出于某种奇怪的原因,您仍然希望您的对象驻留在堆栈上,您可以使用placement-new,如下面的代码片段所示。Placement-new将尝试使用您传递给它的地址并将对象放在那里。

#include <type_traits>

typedef std::multimap<std::string,std::string> SSMap;

std::aligned_storage<
  sizeof(SSMap), std::alignment_of<SSMap>::value
>::type storage;

SSMap& gciting = * new (&storage) SSMap;

/* use gciting exactly as before */

在 C++03 中,确保正确对齐的最佳/最简单方法是使用malloc分配内存,以满足可用的最严格对齐(适用于每种类型)。

话虽如此,没有简单的方法让对象仍然驻留在堆栈上,尽管使用对象的接口保持不变,但我们仍然可以创建对驻留在堆上的对象的引用。

#include <cstdlib>
typedef std::multimap<std::string,std::string> SSMap;

char * storage = static_cast<char*> (std::malloc (sizeof (SSMap))); 
SSMap& gciting = *new (storage) SSMap;

/* use gciting exactly as before */
于 2012-07-18T22:21:44.847 回答