Rumah >pembangunan bahagian belakang >C++ >Mengapa Pengkompil Mengoptimumkan Lambdas Lebih Baik Daripada Fungsi Biasa?

Mengapa Pengkompil Mengoptimumkan Lambdas Lebih Baik Daripada Fungsi Biasa?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-02 02:20:09184semak imbas

Why Do Compilers Optimize Lambdas Better Than Plain Functions?

Pengoptimuman Fungsi Lambda

Nicolai Josuttis mendakwa dalam "The C Standard Library" bahawa penyusun mengoptimumkan lambda lebih baik daripada fungsi biasa. Ini menimbulkan persoalan mengapa ini berlaku.

Pengoptimuman Sebaris

Orang mungkin menganggap bahawa pengoptimuman sebaris tidak akan membezakan antara lambdas dan fungsi biasa. Walau bagaimanapun, perbezaan utama terletak pada sifat lambda sebagai objek fungsi.

Objek Fungsi lwn. Penunjuk Fungsi

Apabila lambda dihantar ke templat fungsi, ia mencipta fungsi baharu khusus untuk objek itu, menghasilkan panggilan fungsi yang tidak dapat disambungkan secara remeh. Sebaliknya, fungsi biasa menghantar penunjuk fungsi, yang biasanya menyebabkan masalah untuk pengoptimuman sebaris. Penyusun boleh secara teorinya menyelaraskan panggilan sedemikian, tetapi hanya jika fungsi di sekelilingnya juga diselaraskan.

Contoh

Pertimbangkan peta templat fungsi yang mengambil lelaran dan objek fungsi sebagai parameter:

template <typename Iter, typename F>
void map(Iter begin, Iter end, F f) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Menyebut templat ini dengan a lambda:

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), [](int n) { return n * 2; });

Mencipta instantiasi baharu bagi fungsi:

template <>
void map<int*, _some_lambda_type>(int* begin, int* end, _some_lambda_type f) {
    for (; begin != end; ++begin)
        *begin = f.operator()(*begin);
}

Pengkompil boleh dengan mudah membuat panggilan sebaris ke operator lambda().

Walau bagaimanapun, apabila menggunakan penuding fungsi:

int a[] = { 1, 2, 3, 4 };
map(begin(a), end(a), &my_function);

Instasiasi yang terhasil menjadi:

template <>
void map<int*, int (*)(int)>(int* begin, int* end, int (*f)(int)) {
    for (; begin != end; ++begin)
        *begin = f(*begin);
}

Di sini, f menunjuk ke alamat yang berbeza untuk setiap panggilan untuk memetakan, melarang pengoptimuman sebaris melainkan panggilan untuk memetakan di sekelilingnya turut diselaraskan.

Oleh itu, kelebihan pengoptimuman bagi lambdas berpunca daripada keupayaan mereka untuk mencipta objek fungsi yang membolehkan keupayaan sebaris yang remeh.

Atas ialah kandungan terperinci Mengapa Pengkompil Mengoptimumkan Lambdas Lebih Baik Daripada Fungsi Biasa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn