在 Visual Studio 之外启动时程序运行速度较慢
Posted
技术标签:
【中文标题】在 Visual Studio 之外启动时程序运行速度较慢【英文标题】:Program runs slower when launched outside of Visual Studio 【发布时间】:2014-05-02 20:15:30 【问题描述】:我注意到我的程序有一些奇怪的行为。我正在使用 Visual Studio Professional 2013 Update 1 用 C++ 编写它,它由一个链接到多个 DLL 并调用在这些 DLL 中定义的函数的 exe 应用程序组成。
在我的主程序(由数千行代码组成)中,我调用了一个 DLL 函数(我们称之为 DLLFunction()
)并计算该调用所花费的时间,如下所示:
auto beginTime = std::chrono::high_resolution_clock::now();
DllFunction();
auto endTime = std::chrono::high_resolution_clock::now();
long long totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
我注意到,在 Visual Studio 之外启动它需要更长的时间。例如:
在 Visual Studio 中的 debug 中运行它并附加调试器 --> ~50 ms
在 Visual Studio 的 release 中运行它附加调试器 ---> ~25 ms
在 Visual Studio 的 release 中运行它不附加调试器 ---> ~20 ms
在 Visual Studio 之外运行它(发布构建)---> ~80 ms
正如您所见,在 Visual Studio 之外的版本中运行它实际上比运行带有调试器的调试版本需要更长的时间!
有问题的 DLL 是由同一个编译器在同一个解决方案中构建的,我已经仔细检查了我启动应用程序的目录中的所有 DLL 是否都是正确的。
这种行为的原因可能是什么?
编辑 5: 主应用程序生成另一个控制台应用程序并使用命名管道与其通信。事实证明,不生成另一个应用程序会使 DLL 在 Visual Studio 之外快速调用。
但是,在 Visual Studio 内部和外部都生成了相同的应用程序,所以我不明白为什么它会减慢 Visual Studio 外部的其他调用。
编辑 4: 事实证明,这种缓慢的行为只有在我将函数调用放在我的主程序代码的某些部分时才会出现,所以它一定是与此相关的问题。这是很多行,但我会继续研究。
无论如何,感谢您的建议,它们对于识别问题很有用。
编辑 3: 使用 QueryPerfomanceCounter 进行测量:
在 Visual Studio 内部测量的 CPU 周期 (~50k) 是外部 (~110k) 的一半(顺便说一下,QueryPerfomanceCounter() 返回的 CPU 周期是实际的 CPU 周期吗?)。
除以频率显示与 std::chrono 相似的结果。
编辑 2: 我按照建议检查了进程资源管理器,VS内和VS外加载的DLL是相同的。
编辑 1:根据要求,我尝试了这个:
auto beginTime = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 1000; ++i)
DllFunction();
auto endTime = std::chrono::high_resolution_clock::now();
long long totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
结果:
在 Visual Studio 的 release 中运行它附加调试器 ---> ~19 seconds
在 Visual Studio 之外运行它(发布构建)---> ~40 seconds
【问题讨论】:
计时单个函数调用是对代码进行性能测试的错误方法。您需要多次调用它以消除各种可能影响结果的影响(线程调度、上下文切换等)。 即使在 Visual Studio 中也不会计时?无论如何,我尝试循环调用该函数,但 Visual Studio 内部和外部仍然存在很大差异。 @Banex 那有什么区别呢? 它不会以可预测的方式关闭,这是重要的部分。向我们展示您的新代码和时间安排。 @LuchianGrigore 在 Visual Studio 中运行 1000 次 --> ~19 秒;在 Visual Studio 之外 --> ~40 秒 【参考方案1】:在您第一次调用 DLL 之前,该 DLL 不会加载到程序中。如果该函数非常小,则程序可能会花费大部分时间来加载 DLL。 试试改成这样:
DllFunction();
auto beginTime = std::chrono::high_resolution_clock::now();
for (int i = 0; i < 1000; ++i)
DllFunction();
auto endTime = std::chrono::high_resolution_clock::now();
long long totalTime = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - startTime).count();
这种方式不考虑加载时间。
【讨论】:
【参考方案2】:在您第一次运行之前,不会加载有问题的代码,此时它会获取 dll 并将其加载到内存中。由于您在 Visual Studio 中运行,因此可能会在您启动调试器时立即加载所有内容,从而消除首次调用开销。这样做可以防止代码在完全确定需要它之前为加载的 DLL 需要额外空间,并且如果某些引用永远不会被调用,则可以节省空间和时间。
在测试诸如此类的访问时间时,您应该始终将此类测试置于循环中并多次运行它们,因为此类条件会严重影响第一次调用,但不会影响后续调用以及系统的其他条件(例如另一个进程所需的资源)可能会导致波动,您需要将波动弄平以进行良好的测试。永远不要相信单实例执行的时间。
【讨论】:
【参考方案3】:我也会尝试删除代码优化。可能是一些内联函数行为在 VS 调试器中提供了更高的性能。
尝试优化关闭,右键单击您的项目 -> 属性 -> 配置属性 -> C/C++ -> 优化 -> 优化 = 禁用。
【讨论】:
以上是关于在 Visual Studio 之外启动时程序运行速度较慢的主要内容,如果未能解决你的问题,请参考以下文章
Catel 示例在 Visual Studio 中加载非常缓慢