其他分享
首页 > 其他分享> > c – 发布版本中成员函数和全局函数之间的性能差异

c – 发布版本中成员函数和全局函数之间的性能差异

作者:互联网

我已经实现了两个函数来执行两个向量(不是std :: vector)的交叉积,一个是成员函数,另一个是全局函数,这里是关键代码(省略了其他部分)

//for member function
template <typename Scalar>
SquareMatrix<Scalar,3> Vector<Scalar,3>::outerProduct(const Vector<Scalar,3> &vec3) const
{
    SquareMatrix<Scalar,3> result;
    for(unsigned int i = 0; i < 3; ++i)
        for(unsigned int j = 0; j < 3; ++j)
            result(i,j) = (*this)[i]*vec3[j];
    return result;
}

//for global function: Dim = 3
template<typename Scalar, int Dim>
void outerProduct(const Vector<Scalar, Dim> & v1 , const Vector<Scalar, Dim> & v2, SquareMatrix<Scalar, Dim> & m)
{
    for (unsigned int i=0; i<Dim; i++)
        for (unsigned int j=0; j<Dim; j++)
        {
            m(i,j) = v1[i]*v2[j];
        }
}

它们几乎相同,只是一个是具有返回值的成员函数,另一个是全局函数,其中计算的值直接分配给方阵,因此不需要返回值.
实际上,我本来是要用全局的一个替换成员,以提高性能,因为第一个就是复制操作.然而,奇怪的是,全局函数的时间成本几乎是成员函数的两倍.而且,我发现执行了

m(i,j) = v1[i]*v2[j]; // in global function

需要更多的时间

result(i,j) = (*this)[i]*vec3[j]; // in member function

所以问题是,成员和全球职能之间的绩效差异是如何产生的?

有人能说出原因吗?
希望我已经清楚地提出了我的问题,并对我可怜的英语感到抱歉!

// ———————————————— —————————————-
更多信息:
以下是我用来测试性能的代码:

    //the codes below is in a loop
    Vector<double, 3> vec1;
    Vector<double, 3> vec2;
    Timer timer;
    timer.startTimer();
    for (unsigned int i=0; i<100000; i++)
    {
        SquareMatrix<double,3> m = vec1.outerProduct(vec2);
    }
    timer.stopTimer();
    std::cout<<"time cost for member function: "<< timer.getElapsedTime()<<std::endl;

    timer.startTimer();
    SquareMatrix<double,3> m;
    for (unsigned int i=0; i<100000; i++)
    {
        outerProduct(vec1, vec2, m);
    }
    timer.stopTimer();
    std::cout<<"time cost for global function: "<< timer.getElapsedTime()<<std::endl;
    std::system("pause");

并捕获结果:

您可以看到成员功能几乎是全局功能的两倍.
另外,我的项目是基于64位Windows系统构建的,实际上代码用于生成基于Scons构造工具的静态lib文件,以及生成的vs2010项目文件.

我必须提醒一下,奇怪的性能差异只发生在发布版本中,而在调试构建类型中,全局函数几乎比成员版本快五倍.(约0.10s vs 0.02s)

解决方法:

一个可能的解释:

使用内联,在第一种情况下,编译器可能知道结果(i,j)(来自局部变量)不对该[i]或vec3 [j]进行别名,因此这个和vec3的标量数组都没有被修改.

在第二种情况下,从功能的角度来看,变量可能是别名,因此每次写入m都可以修改v1或v2的标量,因此v1 [i]和v2 [j]都不能被缓存.

您可以尝试使用restrict关键字扩展来检查我的假设是否正确.

标签:member-functions,c,performance,global
来源: https://codeday.me/bug/20190829/1763646.html