简体   繁体   English

自执行C ++ 11 lambda的成本

[英]Cost of self-executing C++11 lambdas

Out of a window procedure , I'm writing a switch statement using self-executing lambdas, like this: 窗口过程中 ,我正在使用自执行的lambdas编写一个switch语句,如下所示:

LRESULT CALLBACK proc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
    switch (msg)
    {
        case WM_CREATE: return [&](WPARAM wp, LPARAM lp) {
            do_something(wp, lp);
            return 0;
        }(wp, lp);

        case WM_SIZE: return [&](HWND hWnd) {
            do_another_thing(hWnd);
            return 0;
        }(hWnd);
    }
    return DefWindowProc(hWnd, msg, wp, lp);
}

I believe compilers are free to optimize it pretty much the way they want, but generally speaking, would a compiler add much boilerplate code to this, comparing to not using these lambdas? 我相信编译器可以按照他们想要的方式自由地优化它,但一般来说,编译器会为此添加很多样板代码,而不是使用这些lambdas吗?

Could a compiler detect the redundant lambdas and remove them? 编译器是否可以检测冗余lambda并将其删除?

The question is a bit odd. 这个问题有点奇怪。 The compiler doesn't "remove" the lambdas, because the lambdas are in your source code , and the compiler doesn't modify your source code. 编译器不会“删除”lambda,因为lambdas在你的源代码中 ,并且编译器不会修改你的源代码。 What it does is emit machine code that produces the behaviour of the program you expressed in source code. 它的作用是发出机器代码,产生您在源代码中表达的程序的行为。

The compiler is free to emit as much or as little machine code as it likes as long as the result behaves the way that your program expresses. 只要结果与程序表达的方式相同,编译器就可以自由发出尽可能多的机器代码。

A compiler certainly does not have to emit separate function bodies and jumps/calls between them if it can inline all the code into one place, and that is a commonly applied optimization. 如果编译器可以将所有代码内联到一个位置,那么编译器当然不必发出单独的函数体和它们之间的跳转/调用,这是一种常用的优化。

Optimization questions like this don't have a definite answer in the sense that the optimizer of a compliant compiler can do many, many things. 像这样的优化问题没有明确的答案,因为兼容编译器的优化器可以做很多很多事情。 However, in this case most modern optimizers are almost certainly going to inline the lambda, and generate the same assembly whether or not you use the lambda. 但是,在这种情况下,大多数现代优化器几乎肯定会内联lambda,并生成相同的程序集,无论您是否使用lambda。 Because lambdas have a unique type, the compiler can inline easily. 因为lambdas具有唯一类型,所以编译器可以轻松地内联。 Because the lambda is declared and immediately used and never assigned (a more common name is "immediately invoked/evaluated lambda instead of "self executing"), the compiler knows it can only be called once. So typically it will decide to inline. 因为lambda被声明并立即使用并且从未被赋值(更常见的名称是“立即调用/计算lambda而不是”自执行“),编译器知道它只能被调用一次。所以通常它会决定内联。

To be sure, you can look at some assembly: https://godbolt.org/g/QF6WmR . 可以肯定的是,您可以查看一些程序集: https//godbolt.org/g/QF6WmR As you can see, the generated assembly in this particular example is identical, but obviously it does not prove the general case. 如您所见,此特定示例中生成的程序集是相同的,但显然它不能证明一般情况。

In general, lambdas are considered low or zero cost abstractions in C++, if you think a lambda makes for the cleanest code then use one. 一般来说,lambda在C ++中被认为是低成本或零成本的抽象,如果你认为lambda用于最干净的代码然后使用一个。 If you need to you can always quickly verify the assembly is the same. 如果需要,您可以随时快速验证装配是否相同。 Your reason for using the lambda that way is a bit unusual though; 你以这种方式使用lambda的原因有点不寻常; I wouldn't really consider code folding to be a good reason. 我不会真的认为代码折叠是一个很好的理由。 A more common reason to use immediately evaluated lambdas is to be able to use const in situations where otherwise you can't: 使用立即评估的lambda的一个更常见的原因是能够在不能使用的情况下使用const :否则你不能:

int x;
try {
    x = foo();
}
catch (const ExceptionType& e) {
    x = bar();
} 

vs VS

const auto x = [] () {
    try {
        return foo();
    }
    catch (const ExceptionType& e) {
        return bar();
    }
}();

To persist x in the outside scope in traditional C++ code, we have to declare it first and then assign to it. 要在传统C ++代码中将x保留在外部作用域中,我们必须先声明它然后再分配给它。 By using a lambda that returns the value we want, we can declare and assign x at the same time, allowing it to be const . 通过使用返回我们想要的值的lambda,我们可以同时声明和赋值x ,允许它为const

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM