Convert getSettingsController() to global static object

After looking at the assembly output it became apparent that the Windows
compiler did not compile out the `getSettingsController()` function
call.

This led to an unnecessary function call in order to get the
SettingsController. Turning it into a static object in the compilation
unit scope removes this function call and turns getSettings call into a
single instruction (not counting zeroing the register for comparison and
the jump instruction afterwards).

----

Adding the following code to the `main` function:
```cpp
f ( settings::getSetting( settings::BoolSetting::UTILITY_vrcDebug ) )
{
        LOG( INFO ) << "Enabled";
}
else
{
        LOG( INFO ) << "Disabled";
}
```

Leads to this with the `getSettingsController` function:
```assembly
[...]
    47            if ( settings::getSetting( settings::BoolSetting::UTILITY_vrcDebug ) )
0x7ff6c96819a0  <+ 1024>         call AdvancedSettings!settings::getSettingsController (00007ff6`c96cd280)
0x7ff6c96819a5  <+ 1029>         xorps   xmm0,xmm0
0x7ff6c96819a8  <+ 1032>         cmp     byte ptr [rax+5FCh],0
0x7ff6c96819af  <+ 1039>         je AdvancedSettings!main+0x4fd (00007ff6`c9681a9d)
    49                LOG( INFO ) << "Enabled";
0x7ff6c96819b5  <+ 1045>         mov     qword ptr
[rsp+288h],r15
0x7ff6c96819bd  <+ 1053>         mov     qword ptr
[rsp+290h],rsi
[...]
```

And this without the function:
```assembly
[...]
    47            if ( settings::getSetting( settings::BoolSetting::UTILITY_vrcDebug ) )
0x7ff7d97a19bb  <+ 1019>         xorps   xmm0,xmm0
0x7ff7d97a19be  <+ 1022>         cmp     byte ptr [AdvancedSettings!settings::settingController+0x5fc (00007ff7`d9854d4c)],0
0x7ff7d97a19c5  <+ 1029>         je AdvancedSettings!main+0x4f3 (00007ff7`d97a1ab3)
    49                LOG( INFO ) << "Enabled";
0x7ff7d97a19cb  <+ 1035>         mov     qword ptr
[rsp+288h],r15
0x7ff7d97a19d3  <+ 1043>         mov     qword ptr
[rsp+290h],rsi
[...]
```

Notice the missing `call AdvancedSettings![...]` without the function
and that the settings call literally cannot be made any faster.
This commit is contained in:
Vasily
2019-12-10 08:28:41 +01:00
committed by username223
parent 7cecc6ab69
commit 1465c4a8bd
2 changed files with 13 additions and 18 deletions
+1 -1
View File
@@ -124,7 +124,7 @@ The function is used as a means of controlling when the API will be initialized,
## Implementation
The public imperative API is an abstraction for the implementation, which is contained in a `SettingsController`.
The `SettingsController` object is a `static` object inside the `getSettingsController()` function.
The `SettingsController` object is a `static` object inside the `settings.cpp` compilation unit.
This is done to remove the limitations that an object oriented design would bring, namely lifetime and scope management.
Since the API is supposed to be globally available throughout the lifetime of the program, creating it as an object in the `OverlayController` and passing it to subcontrollers would only introduce unnecessary parameter passing.
+12 -17
View File
@@ -6,63 +6,58 @@
namespace settings
{
SettingsController& getSettingsController()
{
static SettingsController s{};
return s;
}
static SettingsController settingController{};
void saveChangedSettings()
{
getSettingsController().saveChangedSettings();
settingController.saveChangedSettings();
}
void saveAllSettings()
{
LOG( INFO ) << "Saving all settings.";
getSettingsController().saveAllSettings();
settingController.saveAllSettings();
LOG( INFO ) << "All settings saved.";
}
[[nodiscard]] bool getSetting( const BoolSetting setting )
{
return getSettingsController().getSetting<bool>( setting );
return settingController.getSetting<bool>( setting );
}
void setSetting( const BoolSetting setting, const bool value )
{
getSettingsController().setSetting( setting, value );
settingController.setSetting( setting, value );
}
[[nodiscard]] double getSetting( const DoubleSetting setting )
{
return getSettingsController().getSetting<double>( setting );
return settingController.getSetting<double>( setting );
}
void setSetting( const DoubleSetting setting, const double value )
{
getSettingsController().setSetting( setting, value );
settingController.setSetting( setting, value );
}
[[nodiscard]] int getSetting( const IntSetting setting )
{
return getSettingsController().getSetting<int>( setting );
return settingController.getSetting<int>( setting );
}
void setSetting( const IntSetting setting, const int value )
{
getSettingsController().setSetting( setting, value );
settingController.setSetting( setting, value );
}
[[nodiscard]] std::string getSetting( const StringSetting setting )
{
return getSettingsController().getSetting<std::string>( setting );
return settingController.getSetting<std::string>( setting );
}
void setSetting( const StringSetting setting, const std::string value )
{
getSettingsController().setSetting( setting, value );
settingController.setSetting( setting, value );
}
std::string initializeAndGetSettingsPath()
@@ -70,7 +65,7 @@ std::string initializeAndGetSettingsPath()
// The static object is initialized the first time the function is called.
// Having a dedicated function for this allows more control over when this
// happens.
return getSettingsController().getSettingsFileName();
return settingController.getSettingsFileName();
}
} // namespace settings