缓存和复用公共子表达式
【说明】 对于重复使用的表达式,尽量缓存和复用求值后的结果。
【原理】 现代C/C++编译器一般都会做公共子表达式消除,但是不同的编译器或者同一编译器的不同版本优化能力不尽相同。对于一些代数、浮点运算或者稍复杂的结构,编译器还不具备等价变换的能力。
【注意事项】 不涉及
【案例】
优化前:以下代码,存在多次对相同函数GetSomeValue和GetSomeOtherValue的调用:
int Func(int a, int b)
{
int i = a + GetSomeValue();
int j = b + GetSomeOtherValue();
TriggerWorkflow(i, j);
int k = a + b + GetSomeValue() + GetSomeOtherValue();
return k;
}
上述代码生成的指令如下:
Func(int, int):
push {r4, r5, r6, lr}
mov r5, r1
mov r4, r0
bl GetSomeValue()
add r6, r0, r4
bl GetSomeOtherValue()
add r1, r0, r5
mov r0, r6
bl TriggerWorkflow(int, int)
bl GetSomeValue()
add r4, r4, r5
add r4, r4, r0
bl GetSomeOtherValue()
add r0, r4, r0
pop {r4, r5, r6, pc}
优化后:
int Func(int a, int b)
{
int i = a + GetSomeValue();
int j = b + GetSomeOtherValue();
TriggerWorkflow(i, j);
int k = i + j;
return k;
}
优化后生成的汇编指令如下,其中对函数GetSomeValue和GetSomeOtherValue的调用次数减少:
Func(int, int):
push {r4, r5, r6, lr}
mov r4, r1
mov r5, r0
bl GetSomeValue()
add r5, r0, r5
bl GetSomeOtherValue()
add r4, r0, r4
mov r1, r4
mov r0, r5
bl TriggerWorkflow(int, int)
add r0, r5, r4
pop {r4, r5, r6, pc}
父主题: 表达式