我有一段非常脏的代码。
我想稍微优化一下。当我采用以下结构之一或者它们与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
提前致谢!
答案 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)
第二种效率略高于第一次。你保存:
size()
这些是非常小的优化。如果它不影响可读性,请这样做。
答案 4 :(得分:0)
我希望第二种方法在大多数情况下至少略微更优,因为它可以利用参考的位置来访问entity
集合/集合的元素。请注意,在第一种方法中,每个for
循环都需要从头开始访问元素;取决于缓存的大小,列表的大小以及编译器可以推断和优化的程度,当新的for
循环尝试读取元素时,这可能导致缓存未命中,即使该元素具有已被前一个循环读过。