While reading the most upvoted question explaining the Singleton Pattern in C++, I realized some performance issues. The answer proposes the below form for implementing the pattern.
class SomeClass {
public: /** Singleton **/
static SomeClass& instance() {
static SomeClass singleInstance;
return singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
};
When I implement the Singleton in the suggested form, the assembly of the program is as follows. Looking at the output below, I can easily say that the instance()
method includes a branch to test whether it is the first call to the function or not (e.g. whether the static instance was created or not).
SomeClass::instance():
push rbp
mov rbp, rsp
movzx eax, BYTE PTR guard variable for SomeClass::instance()::singleInstance[rip]
test al, al
sete al
test al, al
je .L2
mov edi, OFFSET FLAT:guard variable for SomeClass::instance()::singleInstance
call __cxa_guard_acquire
test eax, eax
setne al
test al, al
je .L2
mov edi, OFFSET FLAT:guard variable for SomeClass::instance()::singleInstance
call __cxa_guard_release
.L2:
mov eax, OFFSET FLAT:SomeClass::instance()::singleInstance
pop rbp
ret
Then, I tried to separate the declaration of the static object from the static instance()
method like below.
class SomeClass {
public: /** Singleton **/
static SomeClass& instance() {
return singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
static SomeClass singleInstance;
};
SomeClass SomeClass::singleInstance; // In the source file
The output of the second program is, as expected, different from the first one. It doesn't include a branch that tests the existence of the Singleton object.
SomeClass::instance():
push rbp
mov rbp, rsp
mov eax, OFFSET FLAT:SomeClass::singleInstance
pop rbp
ret
I've found a similar question explaining the reason for using the in-class static definition of the Singleton instance.
Is it really better to declare the Singleton object outside of the static getter function if the static initialization order isn't a problem?