好吧,过去三天我一直坐在探查器结果面前,通过自动化套件运行各种各样的测试用例.我们的想法是看看是否有任何良好的优化通常可以提高性能.我有资格不错在这方面如下:
在最终用户级别具有非常重要和可观察的性能改进潜力,例如在表现不佳的领域中提高> 100%.
是否有可能减少核心空间使用,例如在数据繁重区域减少> 50%.
易于实现,对代码的混淆最少,副作用最小.即实施优化的好处大大超过了成本.
该应用程序是一个3D映射和建模包,在界面中有大量图形,后端有几何处理.我已经为确保大多数处理的最佳算法选择做了很多工作,而且在这个阶段我正在寻找任何通用的简单方法来处理大型和复杂的数据集时获得额外的优势.到目前为止,我已经提出以下建议;
搜索时,请保留最近找到的项目的缓冲区并首先检查.通过重复搜索进行的大量处理似乎在同一区域内进行搜索.从答案到现在,这似乎是一种特定的记忆形式
排序时,检查数据是否已按排序顺序排列(特别是在使用qsort的位置)
将GUI和处理保持在单独的线程中(失败是易于实现的良好标准,但IMO仍然值得)
如果你有本地类变量,它具有重要的构造/破坏时间,在使用频繁的成员函数中,使它们成为私有类成员.尤其是动态数组和字符串,尤其是MFC CArrays和CStrings.
使用动态数组时,将初始大小设置为略微超过典型使用量,并采用指数增长策略.
处理要存储在数组中的非常大的数据集时,首先调整数据大小以避免任何重新分配.
避免在堆栈上创建临时对象副本的函数返回,而是使用引用参数,例如
CString MyFunc(双x,双y)
效率低于
void MyFunc(double x, double y, CString &Result)
Run Code Online (Sandbox Code Playgroud)
实际上,避免CStrings和大多数MFC在代码的任何性能关键区域.(编辑:这可能更常被RVO否定,但不适用于我的应用中的CStrings)
这些项似乎在我的上下文中运行良好,但有没有明显的我遗漏的,或者还有其他优秀的资源优化?
编辑: 根据提供的许多评论,显然需要进一步解释.虽然我完全意识到建议对特定代码片段进行特定优化需要查看该代码,但过去几天花在分析分析器输出上已经显示出优化候选者方面的某些模式.我也意识到自己对其他人在这个领域做得很好的事情的无知,并且看到这些技术的列举清单(至少对我而言),无论它们是否适用于我的情况.这个问题不是关于优化的危险,但对于那里的任何初学者,我建议你首先建立一个强烈的需求,在首先考虑之前优化需求.我自己的偏好是根据未来的性能要求在设计阶段进行大多数优化,但我也是分析的强力倡导者,以验证在实施中是否满足设计假设.我会请人们取悦他们自己积极优化的经验,而不是他们是否应该首先考虑优化.
FWIW,编译器优化代码与否之间的区别在于我的自动化套件中的12%,这是最终用户级别的边界可观察.
第二次编辑:我发现一些相关的帖子非常有用,特别是Mike Dunlavey关于过度依赖于profiler输出的评论.
请不要抛弃任何旧的'优化是所有邪恶的根源'的东西,这对这个问题完全无关紧要
是的,然后你有这样的事情:
排序时,检查数据是否已按排序顺序排列
让我想知道你是否使用了有效的算法.其中,"过早优化是万恶之源"的基本前提.
并将被投票.
真?那种语气不好.IMO.因人而异.
同样地,我对让编译器为我优化它或者在整个地方抛出内联的乐趣感兴趣.FWIW,编译器优化代码与否之间的区别在于我的自动化套件中的12%,这是最终用户级别的边界可观察.
再加上您手工制作的任何优化,您仍然需要对编译器进行优化.
除此之外,由于您没有提供关于瓶颈位置的特定见解,因此很难提供任何指针.我至少猜到了你:
编辑:因为你说你不知道RVO:尝试阅读移动语义,特别是这个库:来自Adobe的move库.我想Boost会有类似的东西.
编辑#2:还有两件事:
CString MyFunc(double x, double y)效率低于
void MyFunc(double x, double y, CString &Result)
如果MyFunc写得很干净,那么它们应该大致相同.编译器应该能够利用NRVO.这听起来像你已经描述并发现它不是 - 我只是说它可能更符合你的标准,例如"对代码的最小混淆",重新安排功能本身一点点以允许NRVO发生.
还有一些事情要尝试:
Sorted<T>),使这些假设明确.这样,如果你有一个方法,Sorted<vector<T> >例如,你给它一个有序矢量,它直接通过 - 但如果你给它一个vector<T>,它将必须构造一个Sorted<vector<T> >,此时它将对它进行排序.您可以手动断言它是使用替代构造函数进行排序的,但它可以更容易地执行您的假设,也可能会捕获您可能错过的地方.