在C++0x(VS2010下)使用lambda表达式是否会产生任何开销?
我知道使用函数对象会产生开销,但我指的是传递给STL算法的表达式。编译器是否优化这个表达式,消除看起来像函数调用的东西?我开始非常喜欢lambda表达式,但我有点担心速度惩罚。
提前致谢!
在C++0x(VS2010下)使用lambda表达式是否会产生任何开销?
我知道使用函数对象会产生开销,但我指的是传递给STL算法的表达式。编译器是否优化这个表达式,消除看起来像函数调用的东西?我开始非常喜欢lambda表达式,但我有点担心速度惩罚。
提前致谢!
你“知道”函数对象会产生开销?也许你应该重新检查一下事实。 :)
使用STL算法与函数对象相比,通常不会产生任何开销,与手写循环相比也是如此。一个天真的编译器将不得不在函数对象上反复调用operator()
,但这是微不足道的并且可以轻松内联化,因此实际上开销为零。
lambda表达式只是函数对象的语法糖。编译器将代码转换为函数对象,因此它也没有额外的开销。
std::function
实例会显著增加可执行文件的大小。我刚刚进行了这个测试。 - shooshstd::string
实例也会带来很大的开销。但问题和我的回答并不是关于这个的。它们涉及函数对象和 lambda。而 std::function
则不是其中之一。 - jalfstd::function
是一个包装类,对所有可调用对象进行抽象,无论是函数指针还是仿函数。使用它并不免费。但是,如果您避免使用包装器,直接使用一个仿函数或一个 lambda 表达式,则没有任何额外开销。 - jalfT
的函数模板可以将一个lambda作为参数,当然,对于非模板函数,你必须指定实际的参数类型,如果类型是一个lambda,那么你不能这样做,因此在这种情况下,你必须将其包装在std::function
或类似物中。 - jalf在幕后,
void f(char delim)
{
std::for_each( seq.begin()
, seq.end()
, [=](const T& obj){std::cout << obj << delim;} );
}
大约翻译为
class __local_class_name {
char __delim;
public:
__local_class_name(char delim) : __delim(delim) {}
void operator()(const T& obj) {std::cout << obj << __delim;}
};
void f(char delim)
{
std::for_each( seq.begin()
, seq.end()
, __local_class_name(delim) );
}
与所有函数对象一样,开销非常小,因为可以轻松地将调用内联。
[=]
这个符号,表示所有本地对象都将以值的方式被捕获。 - Dennis Zickefoose:(
@jalf:谢谢。我的借口是我还没有时间去尝试这个,所以这一切都是从传闻中打出来的。 - sbi[=]
按值捕获所有内容。我们也可以使用 [delim]
来捕获特定的变量。顺便说一句,我点赞了你的答案。 :) - jalfoperator()
的定义之前写入inline
,或者我只是写了[](){return stuff;}
这一部分,我该如何请求内联? - Born2Smile
std::function
对象中(不需要使用boost,因为它已经被0x标准采纳了)。 - jalf