このタイプのリファクタリングの用語は何ですか


33

次のリファクタリングの用語があると確信していますが、それを思い出すことができず、Google-fuが失敗しています!

リファクタリングは、ステートメントを変更すると、ステートメントが最も影響を与える場所に移動します

$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

これはループ不変コードの動きです。優れたコンパイラーは、独自にそれを行うべきです。

... ループ不変コードは、プログラムのセマンティクスに影響を与えることなくループの本体の外側に移動できるステートメントまたは式(命令型プログラミング言語)で構成されています。ループ不変コードモーションホイストまたはスカラープロモーションとも呼ばれます)は、この動きを自動的に実行するコンパイラ最適化です...

次のサンプルコードを検討すると、2つの最適化を簡単に適用できます。

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

計算x = y + zx * x彼らは内ので、ループの外に移動することができ、ループ不変 -最適化されたコードは、このようなものになりますので、彼らはLOOP-の反復を超える変更しないでください。

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

このコードはさらに最適化できます...


55
優秀なプログラマーも自分でそれを行う必要があります、私は推測
-stijn

8
私は@stijnに同意します-コンパイラに心配させるのが合理的であることがいくつかありますが、これはそれらの1つではありません!
トビー

@Toby:これは新しいコードには当てはまりますが(結局、ループ不変の移動により内部ループが理解しやすくなります)、コンパイラーによって既に行われていることはすべて手作業で行う必要はありません。上記の例のような古いコードはそのままにしておきます。LICMの品質改善はわずかであり、おそらくあなたの時間の価値はありません。
チトン

12
@thiton同意しない。そのままにしておくと、将来のすべてのメンテナーが同じ推論を経なければならないことを意味します。時間を無駄にします。変更するだけです。
イズカタ

2
@zzzzBovはい、知っていますが、私のポイントは、パターンが非表示になると、おそらくパターンとはまったく異なるということです。またはそのようなもの。(ごめん、長い日)
-stijn

10

これは呼ばれますhoistingscalar promotion。こちらをご覧ください

巻き上げとは、ループ自体が操作の結果に影響しないため、ループから何らかの操作を引き出したことを意味します。あなたの場合は、whileループから条件付きテストを引き上げています。

再順序付けとは、結果に影響を与えない方法で命令のシーケンスを変更することを意味します。通常、これはデータに依存しない隣接する命令です。たとえば、次の2つのステートメントを実行する順序は関係ありません。

int a = x;
int b = y;


0

私はそのようなリファクタリングが存在するとは思わない。

したがって、「リファクタリングのリスト」の中から見つけるのは難しいでしょう。

私はその例をリファクタリングではなく最適化として分類します。

私にとって、リファクタリングとは、動作に影響を与えずにコードを変更して理解しやすくすることです。

私にとって最適化とは、パフォーマンスを改善するためにコードを変更することです。

最適化されたコードは理解しにくい傾向があるためです。2つのプラクティスは互いに反する傾向があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.