【发布时间】:2011-04-28 16:41:14
【问题描述】:
我有一个 C++ 程序,它将从二进制文件中读取数据,最初我将数据存储在 std::vector<char*> data 中。我已经更改了我的代码,所以我现在使用字符串而不是 char*,所以 std::vector<std::string> data。例如,我必须做的一些更改是从 strcmp 更改为 compare。
但是我发现我的执行时间急剧增加。对于示例文件,当我使用 char* 时需要 0.38 秒,在我的 Linux 机器上转换为字符串后需要 1.72 秒。我在我的 Windows 机器上观察到一个类似的问题,执行时间从 0.59 秒增加到 1.05 秒。
我相信这个功能会导致速度变慢。它是转换器类的一部分,注意在变量名末尾用_ 指定的私有变量。我显然在这里遇到了内存问题,并且卡在了 C 和 C++ 代码之间。 我希望这是 C++ 代码,所以我更新了底部的代码。
我在另一个函数中也多次访问ids_和names_,所以访问速度非常重要。 通过使用创建map 而不是两个单独的向量,我能够以更稳定的 C++ 代码实现更快的速度。谢谢大家!
NewList.Txt 示例
2515 ABC 23.5 32 -99 1875.7 1
1676 XYZ 12.5 31 -97 530.82 2
279 FOO 45.5 31 -96 530.8 3
旧代码:
void converter::updateNewList(){
FILE* NewList;
char lineBuffer[100];
char* id = 0;
char* name = 0;
int l = 0;
int n;
NewList = fopen("NewList.txt","r");
if (NewList == NULL){
std::cerr << "Error in reading NewList.txt\n";
exit(EXIT_FAILURE);
}
while(!feof(NewList)){
fgets (lineBuffer , 100 , NewList); // Read line
l = 0;
while (!isspace(lineBuffer[l])){
l = l + 1;
}
id = new char[l];
switch (l){
case 1:
n = sprintf (id, "%c", lineBuffer[0]);
break;
case 2:
n = sprintf (id, "%c%c", lineBuffer[0], lineBuffer[1]);
break;
case 3:
n = sprintf (id, "%c%c%c", lineBuffer[0], lineBuffer[1], lineBuffer[2]);
break;
case 4:
n = sprintf (id, "%c%c%c%c", lineBuffer[0], lineBuffer[1], lineBuffer[2],lineBuffer[3]);
break;
default:
n = -1;
break;
}
if (n < 0){
std::cerr << "Error in processing ids from NewList.txt\n";
exit(EXIT_FAILURE);
}
l = l + 1;
int s = l;
while (!isspace(lineBuffer[l])){
l = l + 1;
}
name = new char[l-s];
switch (l-s){
case 2:
n = sprintf (name, "%c%c", lineBuffer[s+0], lineBuffer[s+1]);
break;
case 3:
n = sprintf (name, "%c%c%c", lineBuffer[s+0], lineBuffer[s+1], lineBuffer[s+2]);
break;
case 4:
n = sprintf (name, "%c%c%c%c", lineBuffer[s+0], lineBuffer[s+1], lineBuffer[s+2],lineBuffer[s+3]);
break;
default:
n = -1;
break;
}
if (n < 0){
std::cerr << "Error in processing short name from NewList.txt\n";
exit(EXIT_FAILURE);
}
ids_.push_back ( std::string(id) );
names_.push_back(std::string(name));
}
bool isFound = false;
for (unsigned int i = 0; i < siteNames_.size(); i ++) {
isFound = false;
for (unsigned int j = 0; j < names_.size(); j ++) {
if (siteNames_[i].compare(names_[j]) == 0){
isFound = true;
}
}
}
fclose(NewList);
delete [] id;
delete [] name;
}
C++ 代码
void converter::updateNewList(){
std::ifstream NewList ("NewList.txt");
while(NewList.good()){
unsigned int id (0);
std::string name;
// get the ID and name
NewList >> id >> name;
// ignore the rest of the line
NewList.ignore( std::numeric_limits<std::streamsize>::max(), '\n');
info_.insert(std::pair<std::string, unsigned int>(name,id));
}
NewList.close();
}
更新:后续问题:Bottleneck from comparing strings 并感谢您提供的非常有用的帮助!我以后不会再犯这些错误了!
【问题讨论】:
-
嗯,分析您的代码并查看热点在哪里?然后在这里问关于他们的具体问题?
-
您是否配置调试二进制文件?无论你应该给我们实际的代码差异来寻找瓶颈。
-
代码很丑。这是 C 和 C++ 的混合体。如果你用 C++ 编写,你应该使用 C++ 的东西。
-
仅供参考,您的内存泄漏严重。您只是释放 id 和 name 的最后一个实例。在将数据放在 std::string 向量中的情况下,您可以在每次循环迭代结束时释放内存。对于 char* 向量,您需要迭代向量并删除每个条目。
-
std::fstream 代替 FILE*,std::stringstream 代替 sprintf。
标签: c++ string performance char