DI: benchmark naive lock protected access
...which gives us the dramatic numbers we'd expect. Especially the multithreaded variant contends drastically
This commit is contained in:
parent
d2dababf5c
commit
ff256d9e57
4 changed files with 12 additions and 9 deletions
|
|
@ -102,11 +102,11 @@ main (int, char**)
|
|||
|
||||
Depend<BlackHoleService> mystery;
|
||||
|
||||
cout << microbenchmark<8> ([&]()
|
||||
cout << microbenchmark<1> ([&]()
|
||||
{
|
||||
0 == mystery().readMe();
|
||||
}
|
||||
,200000000)
|
||||
,50000000)
|
||||
<< endl;
|
||||
|
||||
LifecycleHook::trigger (ON_GLOBAL_SHUTDOWN);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace lib {
|
|||
struct DependInject
|
||||
{
|
||||
using Factory = typename Depend<SRV>::Factory;
|
||||
|
||||
using Lock = typename Depend<SRV>::Lock;
|
||||
|
||||
/** configure dependency-injection for type SRV to build a subclass singleton
|
||||
* @tparam SUB concrete subclass type to build on demand when invoking `Depend<SRV>`
|
||||
|
|
@ -259,7 +259,7 @@ namespace lib {
|
|||
static void
|
||||
installFactory (Factory&& otherFac)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Lock guard;
|
||||
if (Depend<SRV>::instance)
|
||||
throw error::Logic("Attempt to reconfigure dependency injection after the fact. "
|
||||
"The previously installed factory (typically Singleton) was already used."
|
||||
|
|
@ -270,7 +270,7 @@ namespace lib {
|
|||
static void
|
||||
temporarilyInstallAlternateFactory (SRV*& stashInstance, Factory& stashFac, Factory&& newFac)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Lock guard;
|
||||
stashFac = move(Depend<SRV>::factory);
|
||||
stashInstance = Depend<SRV>::instance;
|
||||
Depend<SRV>::factory = move(newFac);
|
||||
|
|
@ -280,7 +280,7 @@ namespace lib {
|
|||
static void
|
||||
restoreOriginalFactory (SRV*& stashInstance, Factory& stashFac)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Lock guard;
|
||||
Depend<SRV>::factory = move(stashFac);
|
||||
Depend<SRV>::instance = stashInstance;
|
||||
}
|
||||
|
|
@ -288,7 +288,7 @@ namespace lib {
|
|||
static void
|
||||
activateServiceAccess (SRV& newInstance)
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Lock guard;
|
||||
if (Depend<SRV>::instance)
|
||||
throw error::Logic("Attempt to activate an external service implementation, "
|
||||
"but another instance has already been dependency-injected."
|
||||
|
|
@ -300,7 +300,7 @@ namespace lib {
|
|||
static void
|
||||
deactivateServiceAccess()
|
||||
{
|
||||
ClassLock<SRV> guard;
|
||||
Lock guard;
|
||||
Depend<SRV>::instance = nullptr;
|
||||
Depend<SRV>::factory = Depend<SRV>::disabledFactory;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ namespace lib {
|
|||
class Depend
|
||||
{
|
||||
using Factory = std::function<SRV*()>;
|
||||
using Lock = ClassLock<SRV, NonrecursiveLock_NoWait>;
|
||||
|
||||
static SRV* instance;
|
||||
static Factory factory;
|
||||
|
|
@ -188,6 +189,7 @@ namespace lib {
|
|||
SRV&
|
||||
operator() ()
|
||||
{
|
||||
Lock guard;
|
||||
if (!instance)
|
||||
retrieveInstance();
|
||||
// ENSURE (instance);
|
||||
|
|
@ -198,7 +200,7 @@ namespace lib {
|
|||
void
|
||||
retrieveInstance()
|
||||
{
|
||||
// ClassLock<SRV> guard;
|
||||
// Lock guard;
|
||||
|
||||
// if (!instance)
|
||||
// {
|
||||
|
|
|
|||
|
|
@ -1984,6 +1984,7 @@ The following table lists averaged results in relative numbers, in relation to a
|
|||
|direct invoke shared local object | 15.13| 16.30| ''1.00''| 1.59|
|
||||
|invoke existing object through unique_ptr | 60.76| 63.20| 1.20| 1.64|
|
||||
|lazy init unprotected (not threadsafe) | 27.29| 26.57| 2.37| 3.58|
|
||||
|lazy init always mutex protected | 179,62| 10917.18| 86.40| 6661.23|
|
||||
|
||||
These benchmarks used a dummy service class holding a volatile int, initialised to a random value. The complete code was visible to the compiler and thus eligible for inlining. After accessing this dummy object through the means listed in the table, the benchmarked code retrieved this value repeatedly and compared it to zero. The concurrent measurement used 8 threads (number of cores); as expected, the unprotected lazy init crashed several times randomly during those tests.
|
||||
</pre>
|
||||
|
|
|
|||
Loading…
Reference in a new issue