这种重构的术语是什么


33

我敢肯定,以下的重构术语都有用,但是我不记得了,我的Google-fu让我失望了!

重构将if语句移动到将对其产生最大影响的位置,例如更改此位置

$test = someFunctionThatReturnsABool();
for($x = 0; $x < 10000; $x++) {
    if ($test) { 
        echo $x; 
    }
}

对此

$test = someFunctionThatReturnsABool();
if ($test) {
    for($x = 0; $x < 10000; $x++) {
        echo $x; 
    }
}

Answers:


56

这是循环不变的代码运动。一个好的编译器应该自己完成。

... 循环不变的代码由语句或表达式(使用命令式编程语言)组成,这些语句或表达式可以移到循环主体之外,而不会影响程序的语义。循环不变的代码运动(也称为提升标量提升)是编译器优化,可以自动执行此运动。

如果考虑以下代码示例,则可以轻松应用两个优化。

for (int i = 0; i < n; i++) {
    x = y + z;
    a[i] = 6 * i + x * x;
}

计算x = y + zx * x可以移到循环外,因为它们在循环内是不变的 -它们在循环的迭代中不会改变-因此优化的代码将如下所示:

x = y + z;
t1 = x * x;
for (int i = 0; i < n; i++) {
    a[i] = 6 * i + t1;
}

该代码可以进一步优化...


55
我想,一个好的程序员也应该自己完成它
stijn 2012年

8
我同意@stijn-让编译器担心的某些事情是合理的,但这不是其中之一!
Toby 2012年

@Toby:尽管这对于新代码是正确的(毕竟,循环不变的移动使内部循环更容易理解),但是编译器已经完成的任何事情都不需要手工完成。我只是让上面的示例之类的旧代码站起来;LICM的质量改进很小,可能不值得您花费时间。
thiton

12
@thiton我不同意。保持现状将意味着所有未来的维护者都必须经过相同的推理。浪费时间;只是改变它。
2012年

2
@zzzzBov是的,我知道,但是我的意思是,当隐藏模式时,它可能不再完全是该模式。或类似的东西。(对不起,漫长的一天)
stijn 2012年

10

也称为hoistingscalar promotion。看这里

提升意味着您已将某些操作从循环中拉出,因为循环本身不会影响操作的结果。就您而言,您是将条件测试从while循环中提升出来。

重新排序意味着以不影响结果的方式更改指令顺序。通常,这是没有数据依赖性的相邻指令,例如,执行以下两个语句的顺序无关紧要:

int a = x;
int b = y;


0

我认为不存在这样的重构。

因此,很难在“重构列表”中找到它。

我把那个例子归类为优化而不是重构

对我而言,重构正在更改代码以提高其可理解性,而不影响其行为。

对我而言,优化正在更改代码以提高性能。

由于优化的代码往往不太容易理解。两种做法往往会相互冲突。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.