コンパイラの最適化において、ラムダが関数よりもインライン化に優れているのはなぜですか?

Susan Sarandon
リリース: 2024-11-16 22:55:03
オリジナル
654 人が閲覧しました

Why do Lambdas have an Inlining Advantage Over Functions in Compiler Optimization?

コンパイラの最適化においてラムダが関数よりも優れている理由

Nicolai Josuttis は、著書『The C Standard Library (Second Edition)』の中で、ラムダは次のように主張しています。通常の関数と比較して優れたコンパイラ最適化を享受できます。この区別は、関数オブジェクトとしてのラムダの性質に由来しており、特定のラムダ オブジェクトに合わせた関数テンプレートのインスタンス化が可能です。

ラムダのインライン化の利点

単純な関数とは異なり、関数ポインターを関数テンプレートに渡すと、ラムダは関数オブジェクトとして渡されます。これにより、特定のラムダ オブジェクトに合わせた新しい関数の作成がトリガーされます。その結果、コンパイラはラムダ呼び出しを簡単にインライン化できます。

関数ポインター障害

対照的に、関数は、関数テンプレートの受け渡しメカニズムによって妨げられます。コンパイラーは、関数ポインターを介して行われる呼び出しをインライン化する際に課題に直面します。理論的なインライン化は可能ですが、外側の関数のインライン化も必要です。

インスタンス化の例

以下の関数テンプレート「マップ」を考えてみましょう。

template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}
ログイン後にコピー

ラムダを使用して "map" を呼び出す:

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });
ログイン後にコピー

次のインスタンス化を生成します:

template <>
void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) {
    for (; begin != end; ++begin)
        *begin = f.operator()(*begin);
}
ログイン後にコピー

コンパイラーはラムダの演算子() を識別し、への呼び出しを簡単にインライン化できます。

ただし、「map」が関数ポインターを使用して呼び出される場合:

template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}
ログイン後にコピー

関数ポインター「f」は、「map」の呼び出しごとに異なる場所を指します。コンパイラにとって、「f」呼び出しだけをインライン化するのは困難です。インライン化には、包含する「map」呼び出しもインライン化する必要があり、コンパイラーが「f」が指す特定の関数を判断できるようになります。

以上がコンパイラの最適化において、ラムダが関数よりもインライン化に優れているのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート