首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >关于在C++中优化性能的想法

关于在C++中优化性能的想法
EN

Stack Overflow用户
提问于 2010-02-03 08:44:22
回答 9查看 802关注 0票数 5

好的,在过去的三天里,我一直坐在分析器结果的前面,这是通过通过自动化套件运行相当广泛的测试用例生成的。这样做的目的是看看是否有任何好的优化,通常可以提高性能。在这种情况下,我将很好地限定如下;

  • 有潜力的性能改善,这是非常重要的和可观察到的最终用户级别,例如> 100%的改善,在一个不佳的领域。
  • 具有减少核心空间使用的潜力,例如,在数据密集区域减少50%以上。
  • 易于实现,对代码的混淆最小,副作用最小。也就是说,实施优化的好处大大超过了成本。

该应用程序是一个三维映射和建模软件包,界面上有丰富的图形,后端有几何处理。我已经在确保大多数处理的最佳算法选择方面做了大量工作,在现阶段,我正在寻找在处理大型和复杂数据集时获得额外访问的任何普遍适用的简单方法。到目前为止,我想出了以下几点;

  • 搜索时,保存最近找到的项目的缓冲区,并首先检查。重复搜索的大量处理似乎在同一区域进行搜索。从至今的答案来看,这似乎是回忆录的一种特定形式。
  • 排序时,检查数据没有按排序顺序排列(特别是在使用qsort的位置)。
  • 将GUI和处理保持在单独的线程中(不能满足易于实现的好标准,但IMO仍然值得)
  • 在大量使用的成员函数中,具有大量构造/销毁时间的局部类变量使它们成为私有类成员。特别是动态数组和字符串,特别是MFC CArrays和CStrings。
  • 当使用动态数组时,将初始大小设置为略超过典型使用量,并具有指数增长策略。
  • 当处理要存储在数组中的非常大的数据集时,首先对数据进行大小调整,以避免任何分配。
  • 避免在堆栈上创建临时对象副本的函数返回,而是使用引用参数。 CString MyFunc(double x,double y)

效率不如

代码语言:javascript
复制
void  MyFunc(double x, double y, CString &Result)

实际上,在代码的任何性能关键区域都要避免使用CStrings和大多数MFC。(编辑:这可能更普遍地被RVO否定,尽管在我的应用程序中CStrings不是这样)

这些项目在我的上下文中似乎很有效,但是否有明显的遗漏,或者在优化方面还有其他好的资源呢?

编辑:基于所提供的许多评论,显然需要进一步解释。虽然我完全意识到,为一段特定的代码建议具体的优化需要看到这段代码,但过去几天分析分析器输出的时间已经显示出在优化候选程序方面的某些模式。我也意识到我自己对其他人在这一领域所做的有益的事情的无知,并且看到了(至少对我来说)拥有一份这样的技术清单的价值,不管它们是否适用于我的情况。这个问题并不是关于优化的危险,但是对于任何初学者来说,我建议您首先建立一个强有力的需求,即在考虑之前就需要进行优化。我自己的偏好是在设计阶段根据未来的性能需求执行大多数优化,但我也是剖析的坚定拥护者,以验证在实现中满足了设计假设。我想请人们将他们的答案限制在他们自己的积极优化经验上,而不是他们对是否应该首先考虑优化的信念上。

FWIW,在我的自动化套件中,编译器优化代码和不优化代码之间的区别是12%,这在最终用户级别上是可以观察到的。

第二编辑:一些相关的文章,我发现非常有益,特别是Mike关于变得过于依赖分析器输出的评论。

最后的性能优化策略?

在Linux中,我可以使用什么来分析C++代码?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-02-03 09:10:18

CString MyFunc(double x, double y) 效率不如 void MyFunc(double x, double y, CString &Result)

如果MyFunc写得很干净,它们应该是相同的。编译器应该能够利用NRVO。听起来你已经分析过了,并且发现它不是--我只是说它可能更符合你的标准,例如“对代码的最小混淆”,稍微重新排列函数本身,以允许NRVO发生。

还有几件事要尝试:

  1. 回忆录(类似于您对重复搜索的缓存,但更多关注于树/图的解析,如果有)。
  2. 如果您不需要额外的精度(如果可以的话,甚至可以使用ints ),则使用浮点数而不是双倍。
  3. 使用类型来标记假设(您提到了排序数组-另一个常见的是小写字符串)。创建一个派生或包装类型(例如Sorted<T>),使这些假设显式化。这样,如果你有一个接受一个Sorted<vector<T> >的方法,并且给它一个排序的向量,它会直接通过--但是如果你给它一个vector<T>,它就必须构造一个Sorted<vector<T> >,此时它会对它进行排序。您可以手动断言它是使用另一个构造函数排序的,但它使您更容易携带您的假设,并可能捕捉到您本来可能错过的地方。
  4. 不要放弃内联等。确保你充分意识到他们什么时候应该帮忙,什么时候应该阻止他们。在某些情况下,他们真的可以有所作为--但如果你只是武断地处理它们,可能就不会了。
  5. 您可能从飞重池对象分配器中获益。
  6. 在线程处理时,尽量减少任何交互,这样就可以减少需要锁定的代码数量。通常,即使是相当昂贵的对象的拷贝也比互斥对象更少的开销。显然,在可能的情况下,可以利用原子类型。
票数 5
EN

Stack Overflow用户

发布于 2010-02-03 08:54:31

请不要吐出任何老的‘优化是万恶之源’的东西,这与这个问题完全无关

是的,然后你有这样的事情:

排序时,检查数据是否已按排序顺序排列

让我怀疑你是否在使用有效的算法。这是“过早优化是万恶之源”的基本前提。

也会被否决。

真的?这种语气不好。海事组织。YMMV

类似地,我不感兴趣的是让编译器为我优化它,或者让它到处都是内联。FWIW,在我的自动化套件中,编译器优化代码和不优化代码之间的区别是12%,这在最终用户级别上是可以观察到的。

再加上手工工具的任何优化,您仍然希望编译器优化。

除此之外,由于您没有提供关于瓶颈所在的具体见解,所以很难(如果不是不可能)提供任何指针。我敢猜你至少:

  • 使用自定义分配器
  • 如果您的目标机器是向量机器,则探索使用向量指令的可能性。

编辑:既然你说你不知道RVO:试着阅读移动语义,特别是这个库:来自Adobe的图书馆。我想Boost也会有类似的东西。

Edit#2:还有两件事:

  • 不动点算法可能是一件好事。
  • 尽可能多地使用查找表。
票数 9
EN

Stack Overflow用户

发布于 2010-02-03 08:52:26

我认为您的需求几乎是相互排斥的,除非存在某种明显的缺陷(所有的分析都非常适合查找)。

真正改变性能的事情需要付出很大的努力,而您的基本数据结构是最重要的。减少内存fragm.,对齐内存管理,SIMD,尽可能小的数据结构,尽可能多地分配在一个块中的数据结构,多线程,从模板中减少代码大小,将参数重新声明为局部变量,这样优化器就可以知道它们与优化相同。所有这些都不可能在不花费大量费用的情况下在最后加上去。

很多时候,您甚至无法轻松地度量那些真正影响性能的东西,因为它们只会随着程序的运行或代码大小的增加而变得昂贵。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2190654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档