哪种算法带来最佳性能?

时间:2013-06-25 02:31:08

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

我有一段非常脏的代码。

我想稍微优化一下。当我采用以下结构之一或者它们与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

提前致谢!

5 个答案:

答案 0 :(得分:3)

两者都是O(n)。因为我们不知道各种for循环的内脏,所以不可能这么说。

BTW - 将其标记为伪代码而不是C ++

答案 1 :(得分:3)

第一个可能花费更少的时间递增/测试i并有条件地分支(假设编译器的优化器不会将其减少到相当于第二个),但是使用循环展开时间为无论如何,i循环与循环中花费的时间相比可能无关紧要。

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

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

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

答案 2 :(得分:1)

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

容器的大小可能会影响地点,从而影响性能。所以一般来说,一旦你把数据放到缓存中,你就想尽可能多地咀嚼数据。所以我更喜欢第二种方法。为了获得清晰的图像,您应该实际测量您的表现。

答案 3 :(得分:0)

第二种效率略高于第一次。你保存:

  1. 循环索引的初始化
  2. 致电size()
  3. 将循环索引与size()`
  4. 进行比较
  5. 递增循环索引
  6. 这些是非常小的优化。如果它不影响可读性,请这样做。

答案 4 :(得分:0)

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