【发布时间】:2011-10-18 15:06:51
【问题描述】:
我已将这个简单的方法从 C# 转换为 C++。它读取路径表并填充整数列表(或整数向量的向量)列表。
路径表中的示例行类似于
0 12 5 16 n
我意识到一般来说有更好的方法来做到这一点,但现在我只想知道为什么我的 C++ 代码花费的时间如此要长得多。例如10 分钟而不是 C# 版本的 10 秒。这是我的 C++ 代码。我猜我做错了什么。
//Parses the text path vector into the engine
void Level::PopulatePathVectors(string pathTable)
{
// Read the file line by line.
ifstream myFile(pathTable);
for (unsigned int i = 0; i < nodes.size(); i++)
{
pathLookupVectors.push_back(vector<vector<int>>());
for (unsigned int j = 0; j < nodes.size(); j++)
{
string line;
if (getline(myFile, line)) //Enter if a line is read successfully
{
stringstream ss(line);
istream_iterator<int> begin(ss), end;
pathLookupVectors[i].push_back(vector<int>(begin, end));
}
}
}
myFile.close();
}
这里是 C# 版本:
private void PopulatePathLists(string pathList)
{
// Read the file and display it line by line.
StreamReader streamReader = new StreamReader(pathList);
for (int i = 0; i < nodes.Count; i++)
{
pathLookupLists.Add(new List<List<int>>());
for (int j = 0; j < nodes.Count; j++)
{
string str = streamReader.ReadLine();
pathLookupLists[i].Add(new List<int>());
//For every string (list of ints) - put each one into these lists
int count = 0;
string tempString = "";
while (str[count].ToString() != "n") //While character does not equal null terminator
{
if (str[count].ToString() == " ") //Character equals space, set the temp string
//as the node index, and move on
{
pathLookupLists[i][j].Add(Convert.ToInt32(tempString));
tempString = "";
}
else //If characters are adjacent, put them together
{
tempString = tempString + str[count];
}
count++;
}
}
}
streamReader.Close();
}
对不起,这太具体了,但我很难过。
编辑 - 很多人都说他们已经测试过这段代码,而且对他们来说只需要几秒钟。我所知道的是,如果我注释掉对这个函数的调用,程序会在几秒钟内加载。使用函数调用需要 5 分钟。几乎一模一样。我真的很难过。可能是什么问题?
这是它正在使用的PathTable。
编辑 - 我尝试在程序中单独运行该函数,但花了几秒钟,但恐怕我知道的不够多,无法知道如何解决这个问题。显然这不是代码。会是什么呢?我检查了它被调用的位置,看看是否有多个调用,但没有。它在游戏关卡的构造函数中,并且只被调用一次。
编辑 - 我知道代码不是最好的,但这不是重点。它自己运行很快 - 大约 3 秒,这对我来说很好。我试图解决的问题是为什么在项目内部需要这么长时间。
编辑 - 我注释掉了除主游戏循环之外的所有游戏代码。我将该方法放入代码的初始化部分,该部分在启动时运行一次。除了一些设置窗口的方法外,它现在与只有方法的程序几乎相同,只是它仍然需要大约 5 分钟才能运行。现在我知道它与 pathLookupVectors 的依赖无关。另外,我知道计算机开始写入硬盘驱动器不是内存问题,因为当慢速程序正在运行该方法时,我可以打开另一个 Visual Studio 实例并同时运行单个方法程序,这样就完成了马上。我意识到问题可能是一些基本设置,但如果这确实令人失望地最终成为原因,我没有经历过如此道歉。我仍然不知道为什么要花这么长时间。
【问题讨论】:
-
你在编译优化吗?
-
为什么C++版本用str[count]!='\n',第二个用str[count].ToString()!="\n"?
-
@MikeSeymour 我不认为优化将占 C++ 方法所花费的所有 9 分 50 秒的额外时间。您是否尝试过调试并比较执行流程?我的猜测是这样的差异存在某种逻辑问题导致 C++ 方法循环更多。
-
只是猜测:
size()在您使用的集合类型中是 O(1) 还是 O(n) 操作?你对它进行 O(n^2) 调用,如果它们都是 O(n),那么这就是 O(n^3) 的总成本,这是相当多的。但是,与其从互联网上征求随机猜测,不如通过分析器运行代码并自己回答问题,看看它说了什么? -
@SirYakalot:您介意发布两个项目的完整代码吗?我想看看这个完整的上下文。当然不是在这里,而是在某个文件托管站点,只需给我链接。虽然不承诺任何结果。