-1

我有一段非常脏的代码。

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

提前致谢!

4

5 回答 5

3

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

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

于 2013-06-25T02:37:10.030 回答
3

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

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

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

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

于 2013-06-25T02:39:12.110 回答
1

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

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

于 2013-06-25T02:44:04.503 回答
0

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

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

这些都是非常小的优化。如果它不影响可读性,请执行此操作。

于 2013-06-25T02:39:37.280 回答
0

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

于 2013-06-25T02:41:04.497 回答