【发布时间】:2013-09-08 06:24:46
【问题描述】:
Why C++ lambda is slower than ordinary function when called multiple times? 和 C++0x Lambda overhead 中已经提到了这一点 但我认为我的例子与前者的讨论有些不同,与后者的结果相矛盾。
在我的代码中搜索瓶颈时,我发现了一个递归模板函数,它使用给定的处理器函数处理可变参数列表,例如将值复制到缓冲区中。
template <typename T>
void ProcessArguments(std::function<void(const T &)> process)
{}
template <typename T, typename HEAD, typename ... TAIL>
void ProcessArguments(std::function<void(const T &)> process, const HEAD &head, const TAIL &... tail)
{
process(head);
ProcessArguments(process, tail...);
}
我将使用此代码的程序的运行时间与 lambda 函数以及使用移动指针将参数复制到全局缓冲区的全局函数进行了比较:
int buffer[10];
int main(int argc, char **argv)
{
int *p = buffer;
for (unsigned long int i = 0; i < 10E6; ++i)
{
p = buffer;
ProcessArguments<int>([&p](const int &v) { *p++ = v; }, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}
}
用 g++ 4.6 和 -O3 编译,用工具测量时间在我的机器上需要超过 6 秒,而
int buffer[10];
int *p = buffer;
void CopyIntoBuffer(const int &value)
{
*p++ = value;
}
int main(int argc, char **argv)
{
int *p = buffer;
for (unsigned long int i = 0; i < 10E6; ++i)
{
p = buffer;
ProcessArguments<int>(CopyIntoBuffer, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}
return 0;
}
大约需要 1.4 秒。
我不明白幕后发生的事情解释了时间开销,我想知道是否可以更改某些内容以使用 lambda 函数而无需支付运行时费用。
【问题讨论】:
-
那么全球的真的慢吗?你说它是 6s vs. 1.4 的基于 lambda 的,但是最后一句话没有意义。
-
在进行分析时,您是否查看了生成的程序集列表?
-
将
process传递给const引用,像这样void ProcessArguments(const std::function<void(const T &)> &process),有什么不同吗? -
@cmaster 好吧,把你的马留在这里。除了这个基准是有缺陷的事实之外——即使这是真的,它也只对闭包起作用。非闭包 lambda 有 no 开销。这是事实。并且闭包也不会,在通常的代码中 - OP 是作弊,非 lambda 代码使用全局对象,这通常不是一个选项:通常你必须手动实现闭包,然后你再一次具有与 lambda 完全相同的开销。如果有的话,这是反对使用
std::function(在特定情况下)的论据,而不是反对 lambdas。
标签: c++ performance lambda variadic-templates