首页 > 解决方案 > 在普通函数上使用静态成员函数是否有任何开销?

问题描述

我正在使用模板类来制作函数。所以我决定在一个类中定义函数。

template<class T>
struct A
{
    static T F(){}
    static T F1(){}
};

结构内没有我需要使用的变量。我正在使用A<int>::F(). 时间对我的工作非常重要(甚至纳秒)。转向简单的模板函数(未在类或结构中定义)有什么好处吗?

标签: c++functionc++11static

解决方案


简而言之

不,模板函数调用或静态成员函数调用在运行时不会产生开销。所以请继续。如果你的分析器告诉你一些事情,你当然可能会带着另一个问题回来:-)

更多细节

模板是一项编译时业务。因此,由于模板替换,调用模板化函数不会在运行时给您带来开销。这与您自己重写函数替换源代码中的类型的性能相同(但后者会非常麻烦)。

示例:

template <class T> 
void f(T& a, T*p)
{ a = *p; }

void fi(int& a, int*p)
{ a = *p; }

int test (int& x) {
    fi(x, pi); // or f(x, pi);  
}

Godbolt bith withfi()或 with生成的代码f()实际上是相同的(请注意,优化器内联调用,这也将为您节省几个 CPU 周期):

test(int&):
        mov     rax, QWORD PTR pi[rip]
        mov     eax, DWORD PTR [rax]
        mov     DWORD PTR [rdi], eax

静态函数本身也不会引入任何运行时开销。静态函数调用甚至可能比非静态成员函数更快,因为普通成员函数在调用时需要在后台做一些额外的事情,以确保函数知道调用它的对象。

例子:

struct A {
    static int fs();
    int fns(); 
};
extern A a;      

int test (int& x) {
    A::fs();
    a.fns();  
}

Godbolt这次生成了如下代码:

test(int&):
     sub     rsp, 8

     call    A::fs()             ; static call is just a call in assembler

     mov     edi, OFFSET FLAT:a  ; non-static needs to pass object's address
     call    A::fns()            ; before the call can be made

推荐阅读