C ++多图导致程序退出缓慢?

时间:2012-07-18 22:15:30

标签: c++ stl multimap

我有一个程序从.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;
}

2 个答案:

答案 0 :(得分:5)

是的,std容器的析构函数需要一段时间才能管理内存(在您的情况下,它们会管理它们包含的std::string内存)并且它们包含很多元素。 / p>

如果您不介意内存泄漏(这不是泄漏,因为它不会持续泄漏且受到控制),您可以动态分配地图并忘记删除它:

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;
}

答案 1 :(得分:5)

如何让我的物体不被破坏?

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

这通常不推荐使用,但今天的主要操作系统足够聪明,可以在应用程序终止时将任何已分配的内存释放回操作系统,因此使用此方法应该安全。< / p>


请注意我在上面使用了“ should ”而不是“”。

标准中没有任何内容表示分配的内存将被释放回操作系统,或者如果您不释放它将会发生什么(除了泄漏之外)。

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

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


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

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

尝试在启用优化标记的情况下编译它,并在(通常称为)释放模式中进行编译。


使用展示位置..

如果您,出于某种奇怪的原因,仍然希望您的对象驻留在堆栈上,您可以使用 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 */