Jaki jest termin tego typu refaktoryzacji

33

Jestem pewien, że istnieje termin na ponowną refaktoryzację, ale nie pamiętam go, a mój Google-fu mnie zawodzi!

Refaktor przesuwa się, jeśli instrukcje, do których będą miały największy wpływ, na przykład zmieniając to

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

Do tego

$test = someFunctionThatReturnsABool();
if ($test) {
    for($x = 0; $x < 10000; $x++) {
        echo $x; 
    }
}
Toby
źródło

Odpowiedzi:

56

Jest to ruch kodu niezmienny w pętli . Dobry kompilator powinien zrobić to sam.

... kod niezmienny w pętli składa się z instrukcji lub wyrażeń (w imperatywnym języku programowania ), które można przenieść poza ciało pętli bez wpływu na semantykę programu. Niezmienny ruch kodu (zwany także podnoszeniem lub promocją skalarną ) to optymalizacja kompilatora, która wykonuje ten ruch automatycznie ...

Jeśli weźmiemy pod uwagę poniższy przykład kodu, można łatwo zastosować dwie optymalizacje.

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

Obliczanie x = y + zi x * xmogą być przenoszone na zewnątrz pętli od wewnątrz są niezmiennik pętli - nie zmieni w ciągu iteracji pętli loop tak zoptymalizowany kod będzie coś takiego:

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

Ten kod można dalej optymalizować ...

Thiton
źródło
55
dobry programista powinien to zrobić sam, tak myślę
stijn
8
Zgadzam się @stijn - jest kilka rzeczy, na które rozsądnie jest pozwolić kompilatorowi się martwić, ale to nie jest jedna z nich!
Toby
@Toby: Chociaż dotyczy to nowego kodu (w końcu ruch niezmienny w pętli zapewnia łatwiejszą do zrozumienia pętlę wewnętrzną), wszystko, co jest już zrobione przez kompilator, nie musi być wykonywane ręcznie. Po prostu pozwolę, aby stary kod, taki jak powyższy przykład, stał; poprawa jakości LICM jest niewielka i prawdopodobnie nie warta twojego czasu.
thiton
12
@thiton Nie zgadzam się. Pozostawienie tego w obecnym stanie oznacza, że ​​wszyscy przyszli opiekunowie będą musieli przejść przez to samo rozumowanie. Marnuje czas; po prostu to zmień.
Izkata
2
@zzzzBov tak, wiem, ale chodzi mi o to, że kiedy wzór jest ukryty, prawdopodobnie nie jest już taki sam. Czy jakoś tak. (przepraszam, długi dzień)
stijn
10

Jest to również nazywane hoistinglub scalar promotion. Zobacz tutaj :

Podnoszenie oznacza, że ​​wyciągnąłeś pewną operację z pętli, ponieważ sama pętla nie wpływa na wynik operacji. W twoim przypadku wyciągasz test warunkowy z pętli while.

Ponowne zamówienie oznacza zmianę sekwencji instrukcji w sposób, który nie wpływa na wynik. Zwykle byłyby to instrukcje sąsiednie bez zależności danych, np. Nie ma znaczenia, w jakiej kolejności należy wykonać następujące dwie instrukcje:

int a = x;
int b = y;
Maniak
źródło
0

Nie sądzę, że takie refaktoryzacja istnieje.

Trudno byłoby więc znaleźć go wśród „list refaktoryzacji”.

Sklasyfikowałbym ten przykład jako optymalizację, a nie refaktoryzację .

Według mnie refaktoryzacja zmienia kod, aby poprawić jego zrozumiałość bez wpływu na jego zachowanie.

Dla mnie optymalizacja zmienia kod, aby poprawić wydajność.

Ponieważ zoptymalizowany kod jest trudniejszy do zrozumienia. Te dwie praktyki działają przeciwko sobie.

JW01
źródło