Какой термин для этого типа рефакторинга

33

Я уверен, что есть следующий термин для рефакторинга, но я не могу вспомнить его, и мой Google-фу подводит меня!

Рефакторинг перемещается, если операторы туда, где они будут оказывать наибольшее влияние, например, изменяя это

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

К этому

$test = someFunctionThatReturnsABool();
if ($test) {
    for($x = 0; $x < 10000; $x++) {
        echo $x; 
    }
}
Тоби
источник

Ответы:

56

Это циклически инвариантное движение кода . Хороший компилятор должен делать это самостоятельно.

... инвариантный код цикла состоит из операторов или выражений (на императивном языке программирования ), которые можно перемещать за пределы тела цикла, не затрагивая семантику программы. Циклически-инвариантное движение кода (также называемое подъемом или скалярным продвижением ) - это оптимизация компилятора, которая выполняет это движение автоматически ...

Если мы рассмотрим следующий пример кода, две оптимизации могут быть легко применены.

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

Вычисления x = y + zи x * xмогут быть перемещены за пределы цикла, так как внутри они являются инвариантными цикла - они не меняются в течение итераций цикла - поэтому оптимизированный код будет выглядеть примерно так:

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

Этот код можно оптимизировать дальше ...

thiton
источник
55
хороший программист должен делать это и сам по себе, я думаю
stijn
8
Я согласен с @stijn - есть некоторые вещи, о которых стоит подумать компилятору, но это не одна из них!
Тоби
@Toby: Несмотря на то, что это верно для нового кода (в конце концов, инвариантный ход цикла делает более понятным внутренний цикл), все, что уже сделано компилятором, не нужно делать вручную. Я бы просто оставил старый код, такой как приведенный выше пример; улучшение качества LICM невелико и, вероятно, не стоит вашего времени.
Титон
12
@ С этим я не согласен. Оставить все как есть будет означать, что все будущие сопровождающие должны будут проходить одинаковые рассуждения. Это пустая трата времени; просто измени это.
Изката
2
@zzzzBov Да, я знаю, но моя точка зрения такова, что когда шаблон скрыт, он, вероятно, уже не совсем шаблон. Или что-то типа того. (извините, долгий день)
stijn
10

Это также называется hoistingили scalar promotion. Смотрите здесь :

Подъем означает, что вы извлекли некоторую операцию из цикла, потому что сам цикл не влияет на результат операции. В вашем случае вы выводите условный тест из цикла while.

Переупорядочение означает изменение последовательности инструкций таким образом, чтобы это не влияло на результат. Как правило, это будут смежные инструкции без каких-либо зависимостей от данных, например, не имеет значения, в каком порядке вы выполняете следующие два оператора:

int a = x;
int b = y;
Фанат
источник
0

Я не думаю, что такой рефакторинг существует.

Таким образом, было бы трудно найти его среди «списков рефакторингов».

Я бы назвал этот пример оптимизацией, а не рефакторингом .

Для меня рефакторинг - это изменение кода, чтобы улучшить его понятность, не влияя на его поведение.

Для меня оптимизация - это изменение кода для повышения производительности.

Поскольку оптимизированный код менее понятен. Две практики имеют тенденцию работать друг против друга.

JW01
источник