【问题标题】:Which algorithm brings the best performance? [duplicate]哪种算法带来最好的性能? [复制]
【发布时间】:2013-06-21 17:03:53
【问题描述】:

我有一段代码很脏。

我想稍微优化一下。当我采用以下结构之一或者它们与 c++ 中的性能观点相同时,它有什么不同吗?

for(unsigned int i = 1; i < entity.size(); ++i) begin
if
 if ... else ...
for end

for(unsigned int i = 1; i < entity.size(); ++i) begin
if
 if ... else ...
for end

for(unsigned int i = 1; i < entity.size(); ++i) begin
if
 if ... else ...
for end
....

for(unsigned int i = 1; i < entity.size(); ++i) begin
if
 if ... else ...
if
 if ... else ...
if
 if ... else ...
....
for end

提前致谢!

【问题讨论】:

  • 在一个 c++ 问题中,这些开始-结束块很奇怪
  • 实现两者,然后配置文件。
  • 阅读这篇文章会很有用:Why is one loop so much slower than two loops.
  • 这不是 C++ 语法。事实上,很难想象它是任何语言的语法……if if ... else ... 是什么意思?

标签: c++ performance if-statement for-loop


【解决方案1】:

两者都是 O(n)。由于我们不知道各种 for 循环的内容,因此无法说清楚。

顺便说一句 - 将其标记为伪代码而不是 C++

【讨论】:

    【解决方案2】:

    第一个可能会花费更少的时间来增加/测试i 和有条件的分支(假设编译器的优化器不会将其减少到与第二个相同的),但是循环展开 @987654322 所花费的时间无论如何,@循环与在循环中花费的时间相比可能微不足道。

    相反,选择单独循环还是组合循环很可能会影响缓存命中率,这可能会显着影响任何一个版本:这真的取决于代码。例如,如果三个if/else 语句中的每一个都访问索引i 处的不同数组,那么它们将竞争CPU 缓存并且可能会相互拖慢。另一方面,如果他们访问索引 i 处的同一个数组,在某些计算中执行不同的步骤,那么最好在这些内存页面仍在缓存中时执行所有三个步骤。

    除了缓存之外,还有其他潜在影响 - 从影响到寄存器分配、I/O 设备的速度(例如,如果每个循环对来自不同物理驱动器上的不同文件的行/记录进行操作,则处理一些循环中的每个文件,而不是按顺序处理每个文件)等。

    如果您关心,请使用代表性数据对您的实际应用程序进行基准测试。

    【讨论】:

      【解决方案3】:

      仅从循环的结构来看,不能说哪种方法会更快。 从算法上讲,两者具有相同的复杂度 O(n)。但是,根据您对元素执行的操作类型和容器的大小,两者可能具有不同的性能数字。

      容器的大小可能会影响位置,从而影响性能。所以一般来说,一旦你将数据放入缓存,你会尽可能多地咀嚼数据。所以我更喜欢第二种方法。要获得清晰的图像,您应该实际衡量您的方法的性能。

      【讨论】:

        【解决方案4】:

        第二个只比第一个效率高一点。你保存:

        1. 循环索引的初始化
        2. 致电size()
        3. 比较循环索引和 size()`
        4. 增加循环索引

        这些都是非常小的优化。在不影响可读性的情况下这样做。

        【讨论】:

          【解决方案5】:

          我希望第二种方法在大多数情况下至少稍微优化一点,因为它可以利用参考的位置来访问entity 集合/集的元素。请注意,在第一种方法中,每个for 循环都需要从头开始访问元素;根据缓存的大小、列表的大小以及编译器可以推断和优化的程度,当一个新的for 循环尝试读取一个元素时,即使该元素已经被读取,这也可能导致缓存未命中已经通过了前面的循环。

          【讨论】:

          • 正如其他人在回复中指出的那样,第二种方法在循环索引初始化和比较方面也可能稍微更优。
          猜你喜欢
          • 2017-06-27
          • 2011-04-27
          • 2011-02-26
          • 1970-01-01
          • 1970-01-01
          • 2015-01-19
          • 2011-12-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多