【问题标题】:Lambda VS Function [duplicate]Lambda VS函数[重复]
【发布时间】:2014-10-20 15:11:12
【问题描述】:

我刚刚学习完 lambda 表达式,想知道在使用 cout 打印到控制台时,表达式或常规函数是否会执行得更快。

我应该使用

// Lambda expression
auto helloWorld = []()
{
    cout << "Hello World" << endl;
};

// Normal function
void helloWorld()
{
    cout << "Hello World" << endl;
}

注意:我仍然是一个新手程序员,所以请随时指出我可能犯的任何错误。我只会学习

谢谢

【问题讨论】:

  • 一个像样的编译器不应该有任何区别。如果这个问题仍然悬而未决,我将看到一堆我几乎没有得到的程序集。
  • 不是重复的,因为这个问题特别想知道建议的重复中未解决的 lambda 的 content

标签: c++ function lambda


【解决方案1】:

我认为 lambda 在使用 stl 之类的函数时很优雅,或者您想要快速丢弃函数而不命名它们。

sort(v.begin(),
     v.end(),
     [](int a, int b){ return a > b; }
);

但从函数中它并没有更快。

两者的反汇编。

    helloWorld1();
008112A0  mov         ecx,dword ptr ds:[813054h]  
008112A6  push        8119A0h  
008112AB  call        std::operator<<<std::char_traits<char> > (0811780h)  
008112B0  mov         ecx,eax  
008112B2  call        dword ptr ds:[813038h]  
    helloWorld2();
008112B8  mov         ecx,dword ptr ds:[813054h]  
008112BE  push        8119A0h  
008112C3  call        std::operator<<<std::char_traits<char> > (0811780h)  
008112C8  mov         ecx,eax  
008112CA  call        dword ptr ds:[813038h] 

两者都有相同的反汇编。

【讨论】:

  • 你应该用什么选项指定什么编译器的反汇编:你展示了函数本身的汇编,它没有告诉编译器如何优化调用。
  • @quantdev 我使用了 Visual Studio 2013 反汇编。
【解决方案2】:

由于涉及到 IO,所以在乎几个周期的效率是没有意义的。更重要的是简单。功能完全适合您提供的工作,并且不能被击败。对于只有 Lambda 才能解决的工作,...

在 lambda 显然是一个好的解决方案时保留它们。它们的优势和成本使它们成为在复杂情况下使用的非常强大的工具。如果无法在 lambda 和普通函数之间进行选择,那么显而易见的选择不是 lambda。

【讨论】:

  • c++中的Lambda主要是用来传递函数给其他函数的吧?
  • 当然,你可以用 lambda 做的所有事情,你都可以用一个函数对象类来做。与函数或函数对象类相比,lambda 的主要吸引力在于,当您有一个非常特殊的目的时,在当前函数之外通常不会有用。并且打印"Hello World" 的函数可能通常没有用,因此如果在某些特定情况下需要这样的函数,它可能很适合 lambda。
  • IIRC,一个 lambda is 一个函数对象(有自己的有效匿名类和一切)。 lambda 语法确实避免了您必须自己创建这些类,这非常适合一次性场景。
  • +1 获得好答案
【解决方案3】:

Lambda 是一种就地创建函数对象的方法。函数对象通常用在 C 中使用函数指针作为回调的地方。

一个例子可能是 C qsort 函数。为了能够对任何类型的数组进行排序,您必须给它一个函数的地址,该函数将接收指向数组的两个元素的指针并返回和整数,指示第一个是否小于(应该在之前排序)第二个。 :

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

另一边std::sort不需要比较器功能:

template <class RandomAccessIterator>
  void sort (RandomAccessIterator first, RandomAccessIterator last);

但是如果你需要传递一个两个指定一个不同的顺序你可以通过一个函数对象来做到这一点:

template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

您可以像 mohaned 一样使用 lambda 创建该函数对象:

sort(v.begin(),
     v.end(),
     [](int a, int b){ return a > b; }
);

有意使用 lambda、函数对象和函数指针作为参数传递给算法,作为回调以在发生某些事情和类似情况时获得通知。

要将代码划分为有意义的命名片段,您可以将其划分为定义明确的函数。 要将函数作为参数传递给其他函数,函数对象是一种很好的方法。 如果函数对象非常小,只使用了一个,或者你认为给它命名没有好处,你可以把你的函数对象写成 lambda。

您的问题是关于性能的。函数对象(和 lambdas)与函数指针进行比较。他们可以执行得更快。

如果您查看 qsort,它将接收函数的地址,并且每次需要比较时都会调用函数。没有办法内联,因为 qsort 和你的函数是分开编译的。

在 std::sort 示例中,lambda 代码在编译时可用,如果足够简单,编译器将选择内联并避免所有函数调用。

昨天在 isocpp.org 上链接到一篇我强烈推荐的名为 Demystifying C++ lambdas 的精彩博客文章。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-02
    • 2011-03-24
    • 2013-02-23
    • 1970-01-01
    • 2020-02-09
    • 2013-03-11
    • 2017-09-17
    相关资源
    最近更新 更多