Kushal Patil
Kushal Patil

Reputation: 23

Is there any overhead of using static member function over a normal function?

I am using template classes for making functions. So I decided to define the functions inside a class.

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

There are no variables inside the struct that I need to use. I am calling the functions using A<int>::F(). Time is very important to my work (even nanoseconds). Is there any benefit to shift to simple template functions(not defined in a class or struct)?

Upvotes: 1

Views: 310

Answers (1)

Christophe
Christophe

Reputation: 73366

In short

No there's no overhead generated at run-time for template function call or static member function call. So go ahead. If your profiler tells you something, you may of course come back with another question :-)

More details

Templates are a compile-time business. So a call to a templated function will not bring you an overhead at run-time due to template substitution. It's the same performance as if you'd yourself rewrite the function replacing the types in your source code (but the latter would be very cumbersome).

Exemple:

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);  
}

The code generated by godbolt bith with fi() or with f() is eactly the same (note that the optimizer inlined the call, which will save you a couple of CPU cycles as well):

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

Static function do not by themselves introduce any run-time overhead either. Static function calls may even be faster than non-static member functions, because a normal member function, when called, need behind the scene to do some extra stuff to ensure the function knows the object for which it is invoked.

Example:

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

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

Godbolt this time generated the following code:

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

Upvotes: 1

Related Questions