我做了一个小测试,以检查作为std::sort函数的比较器参数的全局函数/仿函数/lambda的性能。仿函数和lambda具有相同的性能。我很惊讶地发现,似乎是最简单的回调的全局函数要慢得多。

#include <stdafx.h>
#include <windows.h>
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;

const int vector_size = 100000;

bool CompareFunction(const string& s1, const string& s2)
{
    return s1[0] < s2[0];  // I know that is crashes on empty string, but this is not the point here
}

struct CompareFunctor
{
    bool operator() (const string& s1, const string& s2)
    {
        return s1[0] < s2[0];
    }
} compareFunctor;

int main()
{
    srand ((unsigned int)time(NULL));
    vector<string> v(vector_size);

    for(size_t i = 0; i < vector_size; ++i)
    {
        ostringstream s;
        s << rand();
        v[i] = s.str().c_str();
    }

    LARGE_INTEGER freq;
    LARGE_INTEGER beginTime, endTime;
    QueryPerformanceFrequency(&freq);
    QueryPerformanceCounter(&beginTime);

    // One of three following lines should be uncommented
    sort(v.begin(), v.end(), CompareFunction);
    // sort(v.begin(), v.end(), compareFunctor);
    // sort(v.begin(), v.end(), [](const string& s1, const string& s2){return s1[0] < s2[0];});

    QueryPerformanceCounter(&endTime);
    float f = (endTime.QuadPart - beginTime.QuadPart) *  1000.0f/freq.QuadPart;      // time in ms
    cout << f << endl;

    return 0;
}

某些Windows特定的代码用于精确的执行时间测量。环境:Windows 7,Visual C++2010。当然,发布配置已启用默认优化。执行时间处理时间:
Global function 2.6 - 3.6 ms   (???)
Functor - 1.7 - 2.4 ms
Lambda - 1.7 - 2.4 ms

那么,为什么全局功能比较慢? VC++编译器有问题,还是其他问题?

最佳答案

内联了lambda和functor版本,有效消除了每次比较时参数的插入和弹出。

尝试使用

inline bool CompareFunction(const string& s1, const string& s2)
{
    return s1[0] < s2[0];  // I know that is crashes on empty string, but this is not the point here
}

看看是否有所作为。请注意,编译器的自动内联会因编译器,构建版本等的不同而有很大差异。令我惊讶的是,编译器不会自动内联全局函数-除非您实际上是在 Debug模式下编译-否则您不应该这样做。做一个性能测试用例。要真正测试内联是否是问题,您应该将测试分为两个文件并分别编译

代替
bool CompareFunction(const string& s1, const string& s2){
    return s1[0] < s2[0];  // I know that is crashes on empty string, but this is not the point here
}


bool CompareFunction(const string& s1, const string& s2);

并将定义放在单独的文件中-说compare.cpp

当您使用它时,也可以使用以下方法来挫败仿函数的内联:
struct CompareFunctor
{
    bool operator() (const string& s1, const string& s2);
} compareFunctor;

并放入一个单独的文件
bool CompareFunctor::operator() (const string& s1, const string& s2)
{
    return s1[0] < s2[0];
}

10-06 05:15
查看更多