Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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++代码,它运行了大约200个ASCII文件,做一些基本的数据处理,并输出一个基本上所有数据的ASCII文件。_C++_C_Optimization_Memory Management_Memory Leaks - Fatal编程技术网

内存/速度问题的一般策略 我有一个C++代码,它运行了大约200个ASCII文件,做一些基本的数据处理,并输出一个基本上所有数据的ASCII文件。

内存/速度问题的一般策略 我有一个C++代码,它运行了大约200个ASCII文件,做一些基本的数据处理,并输出一个基本上所有数据的ASCII文件。,c++,c,optimization,memory-management,memory-leaks,C++,C,Optimization,Memory Management,Memory Leaks,程序一开始运行得非常快,然后在一段时间内急剧减速,也许会逐渐减速一点,然后在其余时间以相当慢的速度运行。也就是说,它在大约5秒内完成了前80个文件,在大约50秒内完成了总共200个文件。每个文件基本相同 我正在寻找关于如何追踪问题或内存泄漏的建议 更多详情: 首先,我会在程序开始时使用fopen(FILE*outputFile,“w”),在程序结束时使用fclose()。前40个文件大约需要4秒钟;然后大约1.5分钟处理约200个文件 我想可能是输出文件阻塞了内存,所以每次迭代(即每次打开新文

程序一开始运行得非常快,然后在一段时间内急剧减速,也许会逐渐减速一点,然后在其余时间以相当慢的速度运行。也就是说,它在大约5秒内完成了前80个文件,在大约50秒内完成了总共200个文件。每个文件基本相同

我正在寻找关于如何追踪问题或内存泄漏的建议


更多详情: 首先,我会在程序开始时使用fopen(FILE*outputFile,“w”),在程序结束时使用fclose()。前40个文件大约需要4秒钟;然后大约1.5分钟处理约200个文件

我想可能是输出文件阻塞了内存,所以每次迭代(即每次打开新文件时)我都将代码更改为fopen(outputFile,“a”),每次关闭输入文件时都将代码更改为fclose()。。。如上所述,这将性能提高到总共约50秒

奇怪的是,这个“修复”会有如此显著的帮助,但并非完全如此

此外,我没有动态分配任何内存(没有调用“新建”或“删除”或“释放”或其他任何功能)。。。。所以我甚至不知道我怎么会有内存泄漏

任何帮助都将不胜感激! 谢谢


代码:

向量dirCon; //使用boost::filesystem存储目录中的每个文件 bool retVal=FileSystem::getDirectoryContents(HOME\u DIR+HISTORY\u DIR,&dirCon,2); int计数器=0; 对于(int i=0;i0){ DateTime dtTemp(splitString.at(0)); goodLines++; /*…处理拆分字符串,使用dtTemp*/ //输出到文件 fprintf(输出文件,“%s\n”,strFromStrVec(splitString).c_str()); } } }//而 fclose(infle); } }//j cout字符串()); } }捕获(常量文件系统错误和ex){ fprintf(stderr,“错误:'%s'!\n”,例如what()); 返回false; } 返回true; } 使用valgrind套件的一部分分析代码。您可以使用以图形方式浏览结果。(尽管它的名字叫什么,但它也可以在callgrind输出上工作。)它是免费的,会给你很棒的细节

您还可以在外部关闭和打开数据采集。所以,从关闭它开始,等到你的程序变慢,在出现问题的时候打开它,然后关闭它。您将看到CPU的去向。如果有必要,在反向观看时只在速度快的时候做同样的事情并进行比较

通常,这个问题会像拇指酸痛一样突出。

使用valgrind套件的一部分分析代码。您可以使用以图形方式浏览结果。(尽管它的名字叫什么,但它也可以在callgrind输出上工作。)它是免费的,会给你很棒的细节

您还可以在外部关闭和打开数据采集。所以,从关闭它开始,等到你的程序变慢,在出现问题的时候打开它,然后关闭它。您将看到CPU的去向。如果有必要,在反向观看时只在速度快的时候做同样的事情并进行比较


通常,这个问题会像拇指酸痛一样突出。

你能分享一下你的程序吗

  • 需要注意的一点是,您使用的数据结构是否不随元素数量的增加而扩展 e、 g.与使用二叉搜索树(nlog(n))或散列(O(1))相比,使用列表保存一百万个元素的遍历/搜索(O(n))速度非常慢

    二,。 你应该看看自己是否健康
    vector<string> dirCon;
    // Uses boost::filesystem to store every file in directory
    bool retVal = FileSystem::getDirectoryContents(HOME_DIR+HISTORY_DIR, &dirCon, 2);
    
    int counter = 0;
    for(int i = 0; i < dirCon.size(); i++) { 
        // Create output file
        FILE *outFile;
        string outputFileName = HOME_DIR ... ;
        // open file as append "a"
        bool ifRet = initFile(outFile, outputFileName.c_str(), "a");
        if(!ifRet) {
            fprintf(stderr, "ERROR ... ");
            return false;
        }       
    
        // Get the topmost directory name
        size_t loc = dirCon.at(i).find_last_of("/");
        string dirName = dirCon.at(i).substr(loc+1, (dirCon.at(i).size()-(loc+1)));
    
        // Get the top directory content
        vector<string> subDirCon;
        bool subRetVal = FileSystem::getDirectoryContents(dirCon.at(i), &subDirCon);
        if(!subRetVal) { fprintf(stderr, "ERROR\n"); return false; }
    
        // Go through each file in directory, look for the one that matches
        for(int j = 0; j < subDirCon.size(); j++) {
    
            // Get filename
            loc = subDirCon.at(j).find_last_of("/");
            string fileName = subDirCon.at(j).substr(loc+1, (subDirCon.at(j).size()-(loc+1)));
    
            // If filename matches desired station, process and store
            if( fileName == string(dirName ...) ) {
                // Open File
                FILE *inFile;
                if(!initFile(inFile, subDirCon.at(j).c_str(), "r")) { 
                    fprintf(stderr, "ERROR: ... !\n");
                    break;
                }
    
                // Parse file line-by-line
                char str[TB_CHARLIMIT_LARGE];
                const char *delim = ",";
                while(true) {
                    vector<string> splitString;
                    fgets(str, TB_CHARLIMIT_LARGE, inFile);
    
                    if(feof(inFile)) { break; }     // break at end of file
                    removeEndLine(str);
    
                    // If non-comment line, parse
                    if(str[0] != COMCHAR){
                        string strString(str);
                        // remove end line char
                        strString.erase(std::remove(strString.begin(), strString.end(), '\n'), strString.end());
                        strcpy(str, strString.c_str());
    
                        char *temp = strtok(str,delim);
                        char *lastTemp;
                        while(temp != NULL) {
                            splitString.push_back(string(temp));
                            temp = strtok(NULL,delim);
                        }
                        if(splitString.size() > 0) { 
                            DateTime dtTemp(splitString.at(0));  
                            goodLines++;
    
                            /*  ... process splitString, use dtTemp ... */
    
                            // Output to file
                            fprintf(outFile, "%s\n", strFromStrVec(splitString).c_str());
                        }
                    }
                } //while
                fclose(inFile); 
            }
        } //j
        cout << "GoodLines = " << goodLines << endl;
    
        fclose(outFile);
    } // i
    
    bool getDirectoryContents(const string dirName, vector<string> *conts) {
        path p(dirName);
        try {
            // Confirm Exists
            if(!exists(p)) {
                fprintf(stderr, "ERROR: '%s' does not exist!\n", dirName.c_str());
                return false;
            }
    
            // Confirm Directory
            if(!is_directory(p)) {
                return false;
            }
    
            conts->clear();
    
            // Store paths to sort later
            typedef vector<path> vec;
            vec v;
    
            copy(directory_iterator(p), directory_iterator(), back_inserter(v));
    
            sort(v.begin(), v.end()); 
    
            for(vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) {
                conts->push_back(it->string());
            }
    
    
        } catch(const filesystem_error& ex) {
            fprintf(stderr, "ERROR: '%s'!\n", ex.what());
            return false;
        }   
    
        return true;
    }
    
    // proc.cpp
    class Foo
    {
      public:
      std::string chew_on(std::string const& line_to_chew_on) {...}
      ...
    };
    
    Foo processor;
    std::string buffer;
    
    // Read/process
    FILE *input=fopen(..., "r");
    char linebuffer[1000+1];
    for (char *line=fgets(linebuffer, 1000, input); line; 
         line=fgets(linebuffer, 1000, input) ) 
    {
        buffer=buffer+processor.chew_on(line);  //(1)
    }
    fclose(input);
    
    // Write
    FILE *output=fopen(...,"w");
    fwrite(buffer.data(), 1, buffer.size(), output);
    fclose(output);
    
        buffer.append(processor.chew_on(line)); // (2)
    
        buffer += processor.chew_on(line);
    
    $ g++ -O0 -g -pg -o proc.o -c proc.cpp
    $ g++ -pg -o proc proc.o
    
    ./proc
    
    $ gprof ./proc Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ms/call ms/call name 100.50 0.01 0.01 234937 0.00 0.00 std::basic_string<...> std::operator+<...>(...) 0.00 0.01 0.00 234937 0.00 0.00 Foo::chew_on(std::string const&) 0.00 0.01 0.00 1 0.00 10.05 do_processing(std::string const&, std::string const&) ...
    $ g++ -O0 -fprofile-arcs -ftest-coverage -o proc proc.cpp
    $ ./proc
    $ gcov ./proc
    ...
    
    -: 0:Source:proc.cpp -: 0:Graph:proc.gcno -: 0:Data:proc.gcda -: 0:Runs:1 -: 0:Programs:1 -: 1:#include -: 2:#include -: 4:class Foo -: 5:{ -: 6: public: 234937: 7: std::string chew_on(std::string const& line_to_chew_on) {return line_to_chew_on;} -: 8:}; -: 9: -: 10: -: 11: 1: 12:int do_processing(std::string const& infile, std::string const& outfile) -: 13:{ -: 14: Foo processor; 2: 15: std::string buffer; -: 16: -: 17: // Read/process 1: 18: FILE *input=fopen(infile.c_str(), "r"); -: 19: char linebuffer[1000+1]; 234938: 20: for (char *line=fgets(linebuffer, 1000, input); line; -: 21: line=fgets(linebuffer, 1000, input) ) -: 22: { 234937: 23: buffer=buffer+processor.chew_on(line); //(1) -: 24: } 1: 25: fclose(input); -: 26: -: 27: // Write 1: 28: FILE *output=fopen(outfile.c_str(),"w"); 1: 29: fwrite(buffer.data(), 1, buffer.size(), output); 1: 30: fclose(output); 1: 31:} -: 32: 1: 33:int main() -: 34:{ 1: 35: do_processing("/usr/share/dict/words","outfile"); -: 36:}
    g++ -O0 -o proc proc.cpp
    valgrind --tool=callgrind ./proc  # this takes forever to run
    kcachegrind callgrind.out.*
    
    bool getDirectoryContents(const string dirName, vector<string> *conts) {
        ...
        copy(directory_iterator(p), directory_iterator(), back_inserter(v));
    
    bool getDirectoryContents(const string dirName, vector<string> *conts) {
        ...
        // note: preincrementing the iterator
        for (directory_iterator it((p)); it!=directory_iterator(); ++it) {
           v.push_back(*it);
        }