[解決済み] なぜラムダはプレーンな関数よりもコンパイラによって最適化できるのですか?
質問
著書の中で
The C++ Standard Library (Second Edition)
Nicolai Josuttisは、ラムダはプレーンな関数よりもコンパイラによって最適化されることがあると述べています。
さらに、C++コンパイラは、ラムダを最適化します。 通常の関数 (213ページ)
それはなぜか?
インライン化に関しては、もう差はないはずだと思ったのですが。ただ、コンパイラーはラムダなどのローカルコンテキストをよりよく理解し、より多くの仮定を立て、より多くの最適化を実行することができるのでしょう。
どのように解決するのですか?
その理由は、ラムダは 関数オブジェクト そのため、関数テンプレートに渡すと、そのオブジェクト専用の新しい関数がインスタンス化されます。そのため、コンパイラはラムダ呼び出しをインライン化することができる。
一方、関数の場合は、昔からある注意事項が適用されます。 ポインタ 関数テンプレートに渡されるため、コンパイラは従来から関数ポインタ経由の呼び出しをインライン化することに多くの問題を抱えていました。そのため できる 理論的にはインライン化できますが、それは周囲の関数もインライン化した場合のみです。
例として、次のような関数テンプレートを考えてみましょう。
template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
for (; begin != end; ++begin)
*begin = f(*begin);
}
こんな感じでラムダで呼び出す。
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);
}
... コンパイラは
_some_lambda_type::operator ()
で、その呼び出しをインライン化することができます。(そして,関数
map
で
任意の
の新しいインスタンスを作成します。
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
を特定の1つの関数に変換します。
関連
-
[解決済み] string does not name a type Errorが発生するのはなぜですか?
-
[解決済み】CMakeエラー at CMakeLists.txt:30 (project)。CMAKE_C_COMPILER が見つかりませんでした。
-
[解決済み] SQLiteのINSERT/per-secondのパフォーマンスを向上させる
-
[解決済み] なぜテンプレートはヘッダーファイルでしか実装できないのですか?
-
[解決済み] なぜ、オブジェクトそのものではなく、ポインタを使用しなければならないのですか?
-
[解決済み] Swift Betaのパフォーマンス:配列のソート
-
[解決済み] Collatz予想の検証を行うC++のコードは、なぜ手書きのアセンブリよりも高速に動作するのでしょうか?
-
[解決済み] noexceptを本当に使うべきはいつですか?
-
[解決済み] なぜリストの初期化(中括弧を使用)が他の方法より優れているのですか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] テスト
-
[解決済み】C++ 非推奨の文字列定数から「char*」への変換について
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】C++ - 解放されるポインタが割り当てられていないエラー
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】標準ライブラリにstd::endlに相当するタブはあるか?
-
[解決済み】C++はC#よりどのくらい速いのか?
-
[解決済み] std::function vs テンプレート
-
[解決済み] C++11で "auto "で演繹した場合のlambdaの型は何ですか?