プログラムまたはコードのスニペットのパフォーマンスを改善しようとする場合 (つまり、より優れたアルゴリズムを使用して同じ結果を計算する場合)、アルゴリズムの目に見える出力を考慮することが重要です。つまり、アルゴリズム (の出力) はどのように使用または消費されるのでしょうか? つまり、アルゴリズムは何を返し、その戻り値はどのように消費されるのでしょうか?
あなたの質問の上記の手順は、リストを作成する必要があることを示していますが、その後はどうすればよいでしょうか? 結果を破棄するだけの場合 (そのようなプログラムや関数は簡単に作成できます)、優れたオプティマイザー (人間または機械) は、結果が決して使用されないという事実に基づいて、null または空のプログラムまたは関数に置き換えることができます。(真剣に:これはベンチマークでよくある問題です。アルゴリズムは生成されたコードのパフォーマンスを測定するために何らかの結果を計算しますが、その結果は使用されないため、コンパイラは潜在的にループ全体、メモリ割り当て、おそらく関数全体を削除します!)
したがって、パフォーマンスを向上させるためにアルゴリズムを変更する方法の分析に関する質問の設定に関して本当に重要なことは、(プログラムの他の部分によって) 使用される出力の部分を特定または指定することです。
仕様 (アルゴリズムの結果がどのように消費されるか) が与えられると、逆方向に作業して、より少ない作業で同じ結果をもたらすアルゴリズムの改善を見つけることができます。
アルゴリズムを構成するとき、構成を調べて改善の機会を特定できます。別の言い方をすれば、上記のアルゴリズムは、一度に 1 つの値のみを見つけるために他のアルゴリズムで使用される可能性があります。つまり、Jeffry のソリューションは、パフォーマンスの優れた適切な置換アルゴリズムです。
ただし、リスト アルゴリズムの別のコンシューマは、その可視効果の別の部分を要求する場合があるため、別の最適化またはアルゴリズムの置換が適切な場合があります。上で説明したように、結果がまったく使用されず、それでも別の消費者がリスト内のノード数をカウントしたい場合がこれに該当します。この場合、まったく異なる最適化がより適切です。
場合によっては、アルゴリズムが何かを返すように指定でき、結果を消費しているのが誰なのかを知らずに何らかの理由でコードを生成する必要があります。そのような場合、オプティマイザー (人間またはマシン) は、返されるすべての可視効果が消費される可能性があるという悲観的な推定を行うことを余儀なくされます。たとえば、リストが(質問の追加仕様として)返されるものであり、オプティマイザーが消費をさらに詳しく調べないようにすると、実際にリストを作成する必要がある可能性が高いと仮定しましょう(したがって、ジェフリーの答えはうまくいきません)。
つまり、追加のコンテキストがなければ、問題とその解決空間を完全に分析することはできません。
部分的には、その追加のコンテキストは、明示的な return ステートメント (または、グローバル変数の変更など、外部から見えるその他の副作用) の形式を取ります。
さらに、その追加のコンテキストの一部は、(目的の元のアルゴリズムを使用して) 囲み、呼び出し、または構成する別のアルゴリズムの形をとる場合があります。したがって、最適化のプロセスは再帰的であり、(人間または機械) が「見る」ことができるほど、より良い結果が得られます。