Quel est le terme pour ce type de refactoring

33

Je suis sûr qu'il y a un terme pour le refactoring suivant, mais je ne m'en souviens pas et mon Google-fu me manque!

Le refactor se déplace si les instructions sont là où elles auront le plus d’impact, par exemple en modifiant cette option.

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

Pour ça

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

Réponses:

56

C'est un mouvement de code invariant de la boucle . Un bon compilateur devrait le faire tout seul.

... Le code invariant des boucles est constitué d'instructions ou d'expressions (dans un langage de programmation impératif ) qui peuvent être déplacées hors du corps d'une boucle sans affecter la sémantique du programme. Le mouvement de code invariant des boucles (également appelé levage ou promotion scalaire ) est une optimisation du compilateur qui effectue ce mouvement automatiquement ...

Si nous considérons l'exemple de code suivant, deux optimisations peuvent être facilement appliquées.

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

Le calcul x = y + zet x * xpeuvent être déplacés en dehors de la boucle car ils sont invariants à la boucle (ils ne changent pas au cours des itérations de la boucle), de sorte que le code optimisé ressemblera à ceci:

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

Ce code peut être optimisé davantage ...

thiton
la source
55
un bon programmeur devrait le faire lui-même aussi, je suppose
lundi
8
Je suis d’accord avec @stijn - il est raisonnable de laisser le compilateur s’inquiéter de certaines choses, mais ce n’est pas l’une d’elles!
Toby
@Toby: Bien que cela soit vrai pour le nouveau code (après tout, le déplacement invariant d'une boucle donne une boucle interne plus facile à comprendre), tout ce qui est déjà fait par le compilateur n'a pas besoin d'être fait à la main. Je laisserais simplement un vieux code tel que l'exemple ci-dessus; l'amélioration de la qualité de LICM est faible et ne vaut probablement pas votre temps.
thiton
12
Je ne suis pas d'accord avec @thiton. Le laisser tel quel signifiera que tous les futurs responsables devront suivre le même raisonnement. Cela fait perdre du temps; il suffit de le changer.
Izkata
2
@zzzzBov oui je le sais, mais ce que je veux dire, c'est que lorsque le motif est caché, ce n'est probablement plus exactement le motif. Ou quelque chose comme ça. (désolé, longue journée)
lundi
10

Ceci est aussi appelé hoistingou scalar promotion. Voir ici :

Le levage signifie que vous avez extrait une opération d'une boucle, car celle-ci n'affecte pas le résultat de l'opération. Dans votre cas, vous retirez le test conditionnel de la boucle while.

Réorganiser signifie changer la séquence d'instructions de manière à ne pas affecter le résultat. En général, il s’agit d’instructions adjacentes sans dépendance de données. Par exemple, l’ordre dans lequel vous exécutez les deux instructions suivantes importe peu:

int a = x;
int b = y;
Geek
la source
0

Je ne pense pas qu'un tel refactoring existe.

Donc, il serait difficile de le trouver parmi les "" listes de refactorisation ".

Je classerais cet exemple dans une optimisation et non dans une refactorisation .

Pour moi, le refactoring consiste à changer le code pour améliorer sa compréhensibilité sans affecter son comportement.

Pour moi, l’optimisation change le code pour améliorer les performances.

Depuis code optimisé a tendance à être moins facile à comprendre. Les deux pratiques ont tendance à se contrarier.

JW01
la source