【问题标题】:Why is a C++ Lambda function much faster as compare function than an equivalent object为什么 C++ Lambda 函数作为比较函数比等效对象快得多
【发布时间】:2016-06-29 23:25:41
【问题描述】:

我很好奇,为什么在我的例子中使用 lambda 函数的实现比使用等效对象的实现要快得多。 给你一个规模的概念:对于 10^4 值,快速的需要不到一秒,慢的需要几十秒。使用 10^5 vales,快速的仍可在一秒钟内完成,但慢的则需要几分钟。

我想对两个数组的值进行排序,就像对其中一个进行排序一样。举个例子更容易理解: [5 1 2 0] 变为 [0 1 2 5] [3 5 6 7] 到 [7 5 6 3]

互联网上有多种方法可以做到这一点,但这不是我想问的。 我做了两种实现:一种使用带有重载 operator() 的对象,另一种使用 lambda 函数作为“比较”。

下面的代码没有注释 lambda 函数版本。要使用比较对象,只需注释掉“使用 lambda 函数比较”中的内容并取消注释“使用比较对象进行比较”即可。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>

void sortTwoVectorsByFirstVector(std::vector< float >& sortBySelf, std::vector< float >& sortByOther)
{
    // init sort indices
    std::vector < uint32_t > sortIndices(sortBySelf.size());
    for (uint32_t i = 0; i < sortIndices.size(); ++i) {
        sortIndices[i] = i;
    }

    //******** begin: compare using compare object
//    struct CompareClass {
//        std::vector< float > m_values;
//        inline bool operator()(size_t i, size_t j)
//        {
//            return (m_values[i] < m_values[j]);
//        }
//    } compareObject { sortBySelf };
//    std::sort(sortIndices.begin(), sortIndices.end(), compareObject);
    //******* end: compare using compare object

    //********  begin: compare using lambda function
    std::sort(sortIndices.begin(), sortIndices.end(), [&sortBySelf](size_t i, size_t j) {return sortBySelf[i] < sortBySelf[j];});
    //********  end: compare using lambda function

    // collect the sorted elements using the indices
    std::vector< float > sortedBySelf_sorted;
    std::vector< float > sortByOther_sorted;
    sortedBySelf_sorted.resize(sortBySelf.size());
    sortByOther_sorted.resize(sortBySelf.size());

    for (uint32_t i = 0; i < sortBySelf.size(); ++i) {
        sortedBySelf_sorted[i] = sortBySelf[sortIndices[i]];
        sortByOther_sorted[i] = sortByOther[sortIndices[i]];
    }

    sortBySelf.swap(sortedBySelf_sorted);
    sortByOther.swap(sortByOther_sorted);
}

float RandomNumber()
{
    return std::rand();
}
int main()
{
    int vectorSize = 100000;
    std::vector< float > a(vectorSize);
    std::vector< float > b(vectorSize);

    std::srand(100);
    std::generate(a.begin(), a.end(), RandomNumber);
    std::generate(b.begin(), b.end(), RandomNumber);

    std::cout << "started" << std::endl;

    sortTwoVectorsByFirstVector(a, b);

    std::cout << "finished" << std::endl;
}

如果有人能弄清楚这个巨大的性能差距来自哪里,那就太酷了。

【问题讨论】:

  • 您手动编写的类会复制向量,而 lambda 表达式不会。
  • 感谢您的快速回答!

标签: c++ sorting optimization lambda


【解决方案1】:

您手动编写的课程复制了vector

std::vector< float > m_values;  //<< By value

lambda 表达式只是引用它:

[&sortBySelf](size_t i, size_t j) {return sortBySelf[i] < sortBySelf[j];}

如果你复制了sortBySelf(没有&amp;),那么它们可能会有类似的性能。

【讨论】:

  • 谢谢!我现在反其道而行之,改变了“std::vector m_values;”到“std::vector& m_values;”。但我不明白的是:复制只完成一次,在初始化时(对吗?)。对于 10^5 个元素,这不会花费几秒钟。
  • @user3022712: std::sort 被允许复制给它的函子任意次数。我可以看到至少复制该函子O(log(n)) 次的幼稚实现。
猜你喜欢
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 1970-01-01
  • 2011-06-21
  • 2012-02-09
  • 2013-05-17
相关资源
最近更新 更多