内存/速度问题的一般策略 我有一个C++代码,它运行了大约200个ASCII文件,做一些基本的数据处理,并输出一个基本上所有数据的ASCII文件。
程序一开始运行得非常快,然后在一段时间内急剧减速,也许会逐渐减速一点,然后在其余时间以相当慢的速度运行。也就是说,它在大约5秒内完成了前80个文件,在大约50秒内完成了总共200个文件。每个文件基本相同 我正在寻找关于如何追踪问题或内存泄漏的建议内存/速度问题的一般策略 我有一个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个文件 我想可能是输出文件阻塞了内存,所以每次迭代(即每次打开新文
更多详情: 首先,我会在程序开始时使用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;i
通常,这个问题会像拇指酸痛一样突出。你能分享一下你的程序吗
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);
}