【发布时间】:2012-02-10 05:58:03
【问题描述】:
我有一个 c++ 代码,它运行大约 200 个 ASCII 文件,进行一些基本的数据处理,并输出一个包含(基本上)所有数据的单个 ASCII 文件。
程序一开始运行得很快,然后在中途急剧减速,也许逐渐减速一点,然后在其余部分以相当慢的速度运行。 IE。它在大约 5 秒内通过前约 80 个文件,在约 50 秒内通过约 200 个总文件。每个文件基本相同。
我正在寻找有关如何追踪问题或内存泄漏的建议。
更多细节: 起初我会在程序的开头使用 fopen(FILE *outputFile, "w") ,最后使用 fclose() 。前约 40 个文件需要约 4 秒;然后大约 1.5 分钟,大约 200 个文件。
我认为可能是输出文件阻塞了内存,所以我将代码更改为 fopen(outputFile, "a") 每次迭代(即每次我打开一个新文件时),每次我关闭输入时 fclose()文件...这将性能提高到总共约 50 秒,如上所述。
奇怪的是,这个“修复”会如此显着,但并非完全有帮助。
另外,我没有动态分配任何内存(没有调用“new”或“delete”或“free”等)......所以我什至不确定我怎么能拥有 内存泄漏。
任何帮助将不胜感激! 谢谢!
代码:
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;
}
【问题讨论】:
-
您可能只是看到了一些奇怪的缓冲行为......但我们需要查看一些代码和诊断才能提供帮助。
-
在一般情况下,您需要优化三个方面:处理器时间、内存使用和 I/O。根据您构建的程序如何处理数据,在任何情况下您可能有也可能没有三个选项中的任何一个来优化。你的程序应该完成什么?
-
试一试Random Pausing。
-
添加代码;希望这有助于解决问题。
-
值得一提的是,您使用的是动态内存。也许不是直接的,但开销仍然存在。
std::vector和std::string都使用动态内存来存储它们的内容。当然,如果您明智地使用 STL,则不太可能发生真正的内存泄漏,但这并不意味着您没有动态内存的开销。
标签: c++ c optimization memory-management memory-leaks