为什么在C ++中是这样的那么多慢? [英] Why is this so much slower in C++?

查看:174
本文介绍了为什么在C ++中是这样的那么多慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经转换从C#和C ++这种简单的方法。它读取路径表并填充整数列表的列表(或整数的向量的向量)。

I have converted this simple method from C# to C++. It reads a path table and populates a list of lists of ints (or a vector of vectors of ints).

从路径表的样本行会是这样的

A sample line from the path table would be something like

0 12 5 16 n

我知道有一般这样做的更好的办法,但现在我只想知道为什么我的C ++代码正在 所以更长。例如为10分钟而不是10秒与C#版本。这里是我的C ++代码。我猜我做的东西有点完全错误的。

I realise there are better ways of doing this in general, but for now I just want to know why my C++ code is taking so much longer. e.g. 10 minutes as opposed to 10 seconds with the C# version. Here is my C++ code. I'm guessing I've done something a bit drastically wrong.

//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();
}



很抱歉,这是如此的具体,但我很为难。

Sorry this is so specific, but I'm stumped.

编辑 - 很多人都表示,他们已经测试此代码,它需要几秒钟他们。我只知道,如果我注释掉调用该函数,以秒为单位的程序加载。在函数调用中需要5分钟。几乎一模一样。我真的难住了。可问题是什么?

EDIT - A lot of people have said they have tested this code, and it takes mere seconds for them. All I know is, if I comment out the call to this function, the program loads in seconds. With the function call it takes 5 minutes. Almost exactly. I'm really stumped. What could the problem be?

下面是的 PathTable 它使用

编辑 - 我想在自己的程序运行的功能,并花了几秒钟,但我怕我不知道够不够才能够知道如何解决这个问题。显然,这是不是代码。什么会是什么?我检查了那里它被称为,看看是否有多个呼叫,但目前还没有。它是在游戏中的级别的一个构造函数和一个只调用一次

EDIT - I tried running the function in a program on its own, and it took a few seconds, but I'm afraid I don't know enough to be able to know how to fix this problem. Obviously it's not the code. What could it be? I checked where it's being called to see if there were multiple calls, but there aren't. It's in a constructor of the game's level and that is only called once.

编辑 - 我明白的代码是不是它可能是最好的,但不是这里的要点。它很快运行在自己的 - 大约3秒,这对我来说很好。我试图解决的问题是为什么需要在项目中要长得多。

EDIT - I understand that the code is not the best it could be, but that isn't the point here. It runs quickly on its own - about 3 seconds and that's fine for me. The problem I'm trying to solve is why it takes so much longer inside the project.

编辑 - 我从游戏主循环注释掉所有的游戏代码分开。我把该方法进入其上启动了一次运行该代码的初始化部分。除了少数方法在一个窗口它现在几乎相同的程序设置为仅与该方法中,只有它仍然需要大约5分钟来运行。现在我知道它有没有关系的pathLookupVectors依赖。另外,我知道这是不是哪里计算机启动写入硬盘驱动器,因为虽然慢程序隆隆离开运行的方法,我可以打开Visual Studio中的另一个实例,并在此​​完成了同时运行的单一方法程序存储器的事以秒为单位。我意识到,问题可能是一些基本的设置,但我没有经历过这样的道歉,如果这并不令人失望,最终成为的原因所在。我还没有一个线索,为什么要花这么长很多。

EDIT - I commented out all of the game code apart from the main game loop. I placed the method into the initialize section of the code which is run once on start up. Apart from a few methods setting up a window it's now pretty much the same as the program with ONLY the method in, only it STILL takes about 5 minutes to run. Now I know it has nothing to do with dependencies on the pathLookupVectors. Also, I know it's not a memory thing where the computer starts writing to the hard drive because while the slow program is chugging away running the method, I can open another instance of Visual Studio and run the single method program at the same time which completes in seconds. I realise that the problem might be some basic settings, but I'm not experienced so apologies if this does disappointingly end up being the reason why. I still don't have a clue why it's taking so much longer.

推荐答案

根据您的更新这是很明显,功能您发表本身不会导致性能问题,所以虽然有在其中您可以优化它似乎是不会帮多方面的。

Based on your update it is pretty clear that the function you posted by itself is not causing the performance problem, so while there are many ways in which you can optimize it it seems that is not going to help.

我相信您可以在每次运行代码的时间,正确的重现这个性能问题?然后,我想建议你做以下测试:

I presume you can reproduce this performance problem every time you run your code, correct? Then I would like to suggest that you do the following tests:


  • 如果您在调试模式下编译程序(即无优化),然后重新编译的版本(全优化,有利于速度),看看是否有差别。

  • if you are compiling your program in debug mode (i.e. no optimizations), then recompile for release (full optimizations, favoring speed) and see if that makes a difference.

要检查是否额外的时间都花在这涉嫌功能,您可以在添加包含时间戳功能的开始和结束的printf语句。如果这不是一个控制台应用程序,但一个GUI应用程序,并用printfs是不会去任何地方,然后写入日志文件。如果你是在Windows上,您也可以使用的 OutputDebugString的,并使用调试器来捕捉printfs输出。如果你是在Linux上,你可以写信给使用日志系统日志。

To check if the extra time is spent on this suspected function you can add printf statements at the start and end of the function that include timestamps. If this is not a console app but a GUI app and printfs are not going anywhere, then write to a log file. If you are on Windows, you can alternatively use OutputDebugString and use a debugger to capture the printfs. If you are on Linux, you can write to the system log using syslog.

使用一个源代码分析器,以确定所有的时间花在哪里。如果调用此函数与否的区别是几分钟,然后探查必将给的线索发生了什么。如果您使用的是Windows,然后很困是一个不错的选择,如果你是在Linux上,你可以使用 OProfile的

Use a source code profiler to determine where is all that time spent. If the difference between calling this function or not is several minutes, then a profiler will surely give a clue as to what is happening. If you are on Windows, then Very Sleepy is a good choice, and if you are on Linux you can use OProfile.

更新:那么,你说,一个发布版本快。则可能意味着您在此函数中使用的库函数具有慢速调试实现。 STL是知道是这样的。

Update: So you say that a release build is fast. That likely means that the library functions that you use in this function have slow debug implementations. The STL is know to be that way.

我敢肯定,你需要调试你的应用程序的其他部分,你不想等待所有那些分钟,此功能在调试模式下完成。这个问题的解决方案是建立在发布模式下你的项目,但改以下列方式释放配置:

I'm sure you need to debug other parts of your application and you don't want to wait all those minutes for this function to complete in debug mode. The solution to this problem is to build your project in release mode, but change the release configuration in the following way:


  • 禁用优化的只为你要调试的文件的(确保优化保持至少启用具有缓慢的函数的文件)。要在文件中禁用优化,请在Solution Explorer中的文件,点击右键,选择属性,然后去配置属性| C / C ++ /优化。看看如何在页面中的所有项目的调试版本设置,并且复制所有这些在你的发布版本的。重复所有要提供给调试器中的文件。

  • disable optimizations only for the files you want to debug (make sure optimizations remain enabled at least for the file that has the slow function). To disable optimizations on a file, select the file in the Solution Explorer, right click, select Properties, then go to Configuration Properties|C/C++/Optimization. Look at how all the items in that page are set for the Debug build, and copy all of those in your Release build. Repeat for all the files that you want to be available to the debugger.

将调试信息(PDB文件)中产生。要做到这一点,选择的项目在解决方案资源管理上,点击右键,选择属性。然后去配置属性|链接器|,调试和复制从调试的所有设置建设成为发布版本

enable debugging info (the pdb file) to be generated. To do this, select the Project at the top of the Solution Explorer, right click, select Properties. Then go to Configuration Properties|Linker|Debugging and copy all the settings from the Debug build into the Release build.

随着上述变化,你将能够调试已配置如上就像你在调试版本做了发布二进制文件的部分。

With the above changes you will be able to debug the parts of the release binary that were configured as above just like you do it in the debug build.

一旦你完成调试则需要所有这些设置恢复,当然。

Once you are done debugging you will need to reset all those settings back, of course.

我希望这有助于。

这篇关于为什么在C ++中是这样的那么多慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆