【发布时间】:2010-02-03 08:44:22
【问题描述】:
好的,过去三天我一直在查看分析器结果,这些结果是通过自动化套件运行大量测试用例生成的。这个想法是看看是否有任何好的优化通常可以提高性能。我将在这种情况下限定 good 如下;
具有性能潜力 两者都非常的改进 结尾显着且可观察 用户级别,例如> 100% 改善 在表现不佳的领域。
具有核心空间的潜力 减少使用量,例如> 减少 50% 在数据密集的领域。
易于实施,最少 混淆代码,并且最小化 副作用。即的好处 大大实施优化 超过成本。
该应用程序是一个 3D 映射和建模包,界面中有大量图形,后端有几何处理。在确保大多数处理的最佳算法选择方面,我已经做了很多工作,在这个阶段,我正在寻找任何普遍适用的简单方法,以便在处理大型和复杂的数据集时获得额外的优势。到目前为止,我想出了以下内容;
搜索时,保留最近找到的项目的缓冲区并首先检查。重复搜索的大量处理似乎在同一区域进行搜索。从迄今为止的答案来看,这似乎是 memoization
的特定形式
排序时,检查数据是否已经按排序顺序(特别是使用 qsort 的位置)
将 GUI 和处理保持在单独的线程中(不符合易于实施的良好标准,但 IMO 仍然值得)
如果你有局部类变量,在大量使用的成员函数中,这些变量具有显着的构造/销毁时间,请将它们设为私有类成员。尤其是动态数组和字符串,尤其是 MFC CArrays 和 CStrings。
使用动态数组时,将初始大小设置为略高于典型使用量,并采用指数增长策略。
在处理要存储在数组中的非常大的数据集时,请先调整数据大小以避免任何重新分配。
-
避免在堆栈上创建临时对象副本的函数返回,而是使用引用参数,例如
CString MyFunc(double x, double y)
效率低于
void MyFunc(double x, double y, CString &Result)
实际上,在代码的任何性能关键区域都避免使用 CString 和大多数 MFC。 (编辑:这可能更普遍地被RVO 否定,尽管不适用于我的应用程序中的 CStrings)
这些项目似乎在我的上下文中运行良好,但有没有我遗漏的明显项目,或者还有其他关于优化的好资源?
编辑:根据提供的许多 cmets,显然需要进一步解释。虽然我完全意识到建议对特定代码段进行特定优化需要查看该代码,但过去几天花在分析分析器输出上的时间已经显示了优化候选者的某些模式。我也知道我自己对其他人在该领域所做的事情的无知,并且认为(至少对我而言)列举这些技术的价值,无论它们是否适用于我的情况。这个问题不是关于优化的危险,但对于任何初学者来说,我建议你在首先考虑之前首先建立一个需要优化的强烈要求。我自己的偏好是在设计阶段根据未来的性能要求进行大部分优化,但我也强烈主张进行分析以验证设计假设在实施中得到满足。我会要求人们将他们的答案限制在他们自己的积极优化经验上,而不是他们的信念上 是否应该首先考虑优化。
FWIW,在我的自动化套件中,让编译器优化代码与否之间的差异为 12%,这在最终用户级别是可以观察到的。
第二次编辑:我发现一些相关的帖子非常有益,尤其是 Mike Dunlavey 的 cmets 关于变得过于依赖分析器输出的文章。
【问题讨论】:
-
complete 引用(没有人使用过)是:“我们应该忘记小的效率,比如说大约 97% 的时间:过早优化是万恶之源”。无论如何,我有自己的一句话:“许多统计数据,比如大约 97%,都是当场制作的。”
-
那么,分析器说大部分时间都花在了哪里?然后弄清楚如何“少做事”。
-
我想说这个问题的答案完全取决于根据您的分析器的热点位置。没有它,我们只是在黑暗中拍摄——谁在乎你是否在热点之外用 CStrings 做了很多低效的事情呢?旁注:将 CStrings 作为返回值返回可能并不像您想象的那样低效——请参阅en.wikipedia.org/wiki/Return_value_optimization。
-
如果您还没有尽量减少内存访问,请为您的数据找到最紧凑的形式。如果你有很好的数据抽象,这应该不会改变你的代码。
-
这不是一个有意义的问题。优化取决于上下文。向我们展示一些代码,我们可以建议如何优化它。如果没有代码,您的问题将毫无意义,尤其是当您限制答案说它们必须至少如此有效时。事实上,这将是我的优化建议:查看您的代码并修复缓慢的位
标签: c++ optimization