8

関数の結果を 1 回格納するのではなく、他の関数を複数回呼び出す関数をよく見かけます。

すなわち(1) :

void ExampleFunction()
{ 
    if (TestFunction() > x || TestFunction() < y || TestFunction() == z)
    {
        a = TestFunction();
        return; 
    }
    b = TestFunction();
}

代わりに、そのように書きます(2) :

void ExampleFunction()
{
    int test = TestFunction();
    if (test > x || test < y || test == z)
    {
        a = test;
        return;
    }
    b = test;
}

バージョン 2 の方が読みやすく、デバッグしやすいと思います。しかし、なぜ人々はナンバー1のようにそれをするのだろうか? 見えないものはありますか?パフォーマンスの問題? 見てみると、(2)の関数呼び出しが1回ではなく、(1)の関数呼び出しが最悪で4回なので、(1)の方が性能が悪いはずですよね?

4

5 に答える 5

3

このような非常に単純な式の結果を格納するために一時的なものが使用される場合、一時的なものは除去されるべき不必要なノイズを導入すると主張することができます。

Martin Fowlerは、著書「リファクタリング:既存のコードの設計の改善」Inline tempで、この一時的なものの排除を、おそらく有益なリファクタリングとして挙げています( )。

これが良い考えであるかどうかは、多くの側面に依存します。

  • 一時的なものは、たとえば意味のある名前を介して、元の式よりも多くの情報を提供しますか?
  • パフォーマンスは重要ですか?お気づきのように、一時的なものがない2番目のバージョンの方が効率的かもしれません(ほとんどのコンパイラーは、副作用がないと仮定して、関数が1回だけ呼び出されるようにそのようなコードを最適化できるはずです)。
  • 関数の後半で一時的に変更されますか?(そうでない場合は、おそらくそうなるはずですconst

結局、そのような一時的なものを導入するか削除するかの選択は、ケースバイケースで行われるべき決定です。コードが読みやすくなる場合は、そのままにしておきます。ノイズだけの場合は取り除いてください。あなたの特定の例では、一時的なものはあまり追加されないと思いますが、実際のコードで使用されている実際の名前を知らなければ、これを判断するのは困難であり、そうではないと感じるかもしれません。

于 2012-09-19T12:31:45.183 に答える
3

コード全体で同じ値が使用されていることを強調したい場合、またはその値の型が であることを強調したい場合は、(2) を使用しますint。真実であるが明らかではないことを強調することで、読者がコードをすばやく理解するのに役立ちます。

これらのどちらも強調したくない場合、特にそれらが真実でない場合、またはTestFunction()副作用のために呼び出される回数が重要な場合は、(1) を使用します。

明らかに、現在はtrue であるが、将来TestFunction()変更されて false になることを強調する場合は、バグがあります。したがって、私はTestFunction()自分自身を制御するか、将来の互換性に関する著者の計画にある程度の信頼を置きたいと考えています. 多くの場合、その信頼は簡単ですTestFunction()。CPU の数を返す場合は、値のスナップショットを取得することに満足しています。int実際に返される型に関係なく。関数を使用するためには、将来の互換性について最小限の確信を持つ必要があります。たとえば、将来、キーボードの数を返さないという確信があります。しかし、インターフェイスが正確に文書化されていない場合は特に、「重大な変更」とは何かについて、人によって考えが異なる場合があります。したがって、 を繰り返し呼び出すTestFunction()ことは、一種の防御的なプログラミングになる場合があります。

于 2012-09-19T12:30:56.330 に答える
1

バージョン 2 の方が読みやすく、デバッグしやすいと思います。

同意した。

したがって、パフォーマンスは番号 (1) の方が悪いはずですよね?

必ずしも。が十分に小さい場合TestFunction、コンパイラは複数の呼び出しを最適化することを決定する場合があります。それ以外の場合、パフォーマンスが重要かどうかは、ExampleFunctionが呼び出される頻度によって異なります。頻繁でない場合は、保守性を最適化します。

また、TestFunction副作用があるかもしれませんが、その場合、コードまたはコメントで何らかの方法でそれを明確にする必要があります。

于 2012-09-19T12:17:13.120 に答える
1

2つは同等ではありません。たとえば、次のとおりです。

int TestFunction()
{
   static int x;
   return x++;
}

しかし、健全な世界では、これは当てはまらず、2 番目のバージョンの方が優れていることに同意します。:)

何らかの理由で関数をインライン化できない場合は、2 番目の関数の方が効率的です。

于 2012-09-19T12:17:44.907 に答える