Qual é o termo para esse tipo de refatoração


33

Tenho certeza de que existe um prazo para a refatoração a seguir, mas não consigo me lembrar e meu Google-fu está falhando comigo!

O refator move se as declarações para onde elas terão maior impacto, por exemplo, alterando isso

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

Para isso

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

Respostas:


56

Este é um movimento de código invariante em loop . Um bom compilador deve fazê-lo por conta própria.

... código invariante de loop consiste em declarações ou expressões (em uma linguagem de programação imperativa ) que podem ser movidas para fora do corpo de um loop sem afetar a semântica do programa. O movimento de código invariante em loop (também chamado de promoção de elevação ou escalar ) é uma otimização de compilador que executa esse movimento automaticamente ...

Se considerarmos o seguinte exemplo de código, duas otimizações podem ser facilmente aplicadas.

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

O cálculo x = y + ze x * xpode ser movido para fora do loop, pois, dentro dele, são invariáveis - eles não mudam nas iterações do loop -, portanto, o código otimizado será algo como isto:

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

Este código pode ser otimizado ainda mais ...


55
um bom programador deve fazê-lo em seu próprio bem, eu acho
Stijn

8
Concordo @stijn - há algumas coisas pelas quais é razoável deixar o compilador se preocupar, mas essa não é uma delas!
26412 Toby

@ Toby: Embora isso seja verdade para o novo código (afinal, o movimento invariante do loop cria um loop interno mais fácil de entender), qualquer coisa que já seja feita pelo compilador não precisa ser feita manualmente. Eu apenas deixaria códigos antigos, como o exemplo acima, permanecerem; a melhoria da qualidade do LICM é pequena e provavelmente não vale o seu tempo.
Th26

12
@thiton Eu discordo. Deixar como está significa que todos os futuros mantenedores teriam que seguir o mesmo raciocínio. Desperdiça tempo; apenas mude.
22712 Izkata

2
@zzzzBov sim, eu sei, mas o que quero dizer é que, quando o padrão está oculto, provavelmente não é mais exatamente o padrão. Ou algo assim. (desculpe, o dia)
Stijn

10

Isso também é chamado hoistingou scalar promotion. Veja aqui :

A elevação significa que você retirou alguma operação de um loop porque o próprio loop não afeta o resultado da operação. No seu caso, você está elevando o teste condicional para fora do loop while.

Reordenar significa alterar a sequência de instruções de uma maneira que não afete o resultado. Normalmente, isso seria instruções adjacentes sem dependências de dados, por exemplo, não importa em qual ordem você executa as duas instruções a seguir:

int a = x;
int b = y;


0

Eu não acho que essa refatoração exista.

Portanto, seria difícil encontrá-lo entre as "listas de refatorações".

Classificaria esse exemplo como uma otimização, não uma refatoração .

Refatorar, para mim, está mudando o código para melhorar sua compreensibilidade sem afetar seu comportamento.

Otimização, para mim, está mudando o código para melhorar o desempenho.

Como o código otimizado tende a ser menos fácil de entender. As duas práticas tendem a trabalhar uma contra a outra.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.