c++ - C++中进行良好性能优化的想法

标签 c++ optimization

好的,在过去三天里,我一直处于分析器结果的前面,该结果是通过自动化套件运行相当多的测试用例而产生的。这样做的目的是查看是否存在可以总体上提高性能的良好优化。在这种情况下,我将取得良好的成绩,具体如下:

  • 具有表现的潜力
    两者都是非常好的改进
    最后重要且可观察
    用户级别,例如> 100%改善
    在表现不佳的地区。
  • 具有潜在的核心空间
    减少使用量减少50%以上
    在数据繁重的区域中。
  • 易于实现,且最少
    对代码的混淆和最小化
    副作用。即...的好处
    极大地实现优化
    超过成本。

  • 该应用程序是一个3d映射和建模程序包,在界面中具有大量图形,并在后端进行了几何处理。我已经在确保为大多数处理选择最佳算法方面做了很多工作,并且在此阶段,我正在寻找任何普遍适用的简便方法来处理大型和复杂数据集。到目前为止,我已经提出了以下建议:
  • 搜索时,请保留最近找到的项目的缓冲区并首先进行检查。重复搜索的大量处理似乎是围绕同一区域进行的。从到目前为止的答案来看,这似乎是memoization
  • 的一种特定形式
  • 排序时,检查数据是否尚未按照排序顺序(特别是在使用qsort的地方)
  • 将GUI和处理保持在单独的线程中(无法实现易于实现的良好标准,但IMO仍然值得)
  • 在频繁使用的成员函数中,具有局部类变量且具有显着的构造/销毁时间的地方,请将它们设为私有(private)类成员。动态数组和字符串,尤其是MFC CArrays和CStrings尤其如此。
  • 使用动态数组时,将初始大小设置为略微超过典型用法,并采用指数增长策略。
  • 处理要存储在数组中的非常大的数据集时,请首先调整数据大小,以避免任何重新分配。
  • 避免函数返回会在堆栈上创建临时对象拷贝,请改用引用参数,例如

    CString MyFunc(double x,double y)

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

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

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

    编辑:根据提供的许多评论,显然需要一些进一步的解释。虽然我完全意识到建议针对特定代码段进行特定优化需要先看一下该代码,但过去两天用于分析探查器输出的结果显示了针对优化候选者的某些模式。我也意识到自己对别人在该领域取得良好成就所做的无知,并且(至少对我而言)看到列举的此类技术的值(value)(无论它们是否适用于我的情况)。这个问题不是关于优化的危险,但是对于那里的任何初学者,我建议您首先考虑对优化的强烈要求,然后再考虑。我自己的喜好是在将来根据性能要求在设计阶段进行大多数优化,但是我还是强烈建议进行性能分析,以验证实现中是否满足设计假设。我想请人们将答案仅限于他们自己的积极优化经验,而不是基于他们的信念。
    我们是否应该首先考虑优化。

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

    第二个编辑:我发现一些相关的帖子非常有益,尤其是Mike Dunlavey关于过于依赖探查器输出的评论。

    Performance optimization strategies of last resort?

    What can I use to profile C++ code in Linux?

    最佳答案

    CString MyFunc(double x, double y)

    is less efficient than

    void MyFunc(double x, double y, CString &Result)



    如果MyFunc书写干净,它们应该大致相同。编译器应该能够利用NRVO。听起来您好像已经进行了概要分析,但发现它不是-我只是说它可能更适合您的条件,例如“对代码的最小混淆”,以稍微重新排列功能本身以使NRVO发生。

    还有更多尝试的方法:
  • 内存(类似于您的缓存
    重复搜索,但更多
    专注于树/图的分辨率,
    如果你有任何)。
  • 如果不需要多余的字符,请使用浮点数而不是 double 数
    精度(如果您愿意,甚至可以是整数
    能够)。
  • 使用类型标记假设(您提到了排序数组-
    另一种常见的是小写字母
    字符串)。创建派生或
    包装类型(例如Sorted<T>)
    使这样的假设明确。那
    如果你有一个方法需要
    例如,Sorted<vector<T> >
    然后给它一个排序的 vector
    直接通过-但是如果您
    给它一个vector<T>,它必须
    在构造了一个Sorted<vector<T> >它将对它进行排序。你可以
    手动断言它已排序
    使用替代构造函数,
    但它使携带更容易
    你的假设,也许
    catch 你可能有的地方
    否则错过。
  • 不要放弃内联等。请确保您完全了解何时
    他们应该提供帮助,何时他们
    应该阻碍。在某些情况下,他们
    确实可以有所作为-但是
    如果您只处理可能不会
    他们任意。
  • 您可能会受益于flyweightpooled object allocators
  • 进行线程处理时,
    尽量减少任何互动,因此
    您可以减少代码量
    需要锁定。经常服用
    甚至相当昂贵的拷贝
    对象可以减少开销
    而不是互斥。明显利用
    可以的原子类型。
  • 关于c++ - C++中进行良好性能优化的想法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2190654/

    相关文章:

    c++ - cURL交叉编译

    c++ - 在 C++11 中推导元组元素的类型

    c++ - 内存交换或文件写入/读取

    python - 为什么 '' .join() 在 Python 中比 += 快?

    python - 让 Numpy.where 在遇到第一个 true 后停止

    mysql - 优化和扩展 mysql 结构 + 大型邮件组的查询

    c++ - UNIX : One running a ruby server and other C++ client 中 2 个进程之间通信的最佳方式

    c++ - 将 vector 的 vector 传递给函数

    c++ - 关于 C++ 中 auto 关键字的困惑

    performance - 缓存相关的性能优化技术?