I've added a performance test module which highlights the issues. Change the debug statements for Database::loadStore and Database::save to debug_i.
loadStore followed by save
There's a call to clearDirty in these setValue tests so there should be no commit. The save is actually happening immediately after the load because of buggy reference handling.
No write caching
Store gets loaded for every update, even though it's already in RAM elsewhere, so repeated updates on same store thrash it.
How to fix?
I had an initial go at this but it the logic at present is too complex so had side effects which made things worse.
We need a better way to deal with this. Notionally we need a second cache for writes, which works in the same way as for reads. The existing updateref mechanism or something similar is still required so we know when a store is locked.
It might be appropriate to use a wrapper class, e.g. StoreRef, for all store updates so reference-counting happens in the constructor/destructor. This may supplement or replace use of shared_ptr.
Test log
Here's the log which shows the problems:
** Performance **
Evaluating load times ...
306 [CFGDB] LoadStore ''
445 [CFGDB] Save ''
Verify load caching: count=32, total=280us, min=0us, max=276us, average=9us
Load all stores: count=32, total=3us, min=0us, max=0us, average=0us
Evaluating setValue / commit ...
628 [CFGDB] LoadStore ''
666 [CFGDB] Save ''
...
3508 [CFGDB] LoadStore ''
3529 [CFGDB] Save ''
setValue [int]: count=32, total=2959us, min=80us, max=140us, average=92us
3607 [CFGDB] LoadStore ''
3633 [CFGDB] Save ''
...
6173 [CFGDB] LoadStore ''
6195 [CFGDB] Save ''
setValue [float]: count=32, total=2646us, min=79us, max=92us, average=83us
6272 [CFGDB] LoadStore ''
6294 [CFGDB] Save ''
6361 [CFGDB] Save ''
...
10711 [CFGDB] LoadStore ''
10733 [CFGDB] Save ''
10791 [CFGDB] Save ''
Set Value + commit: count=32, total=4574us, min=137us, max=158us, average=143us
I've added a performance test module which highlights the issues. Change the debug statements for
Database::loadStore
andDatabase::save
todebug_i
.loadStore followed by save
There's a call to
clearDirty
in thesesetValue
tests so there should be no commit. The save is actually happening immediately after the load because of buggy reference handling.No write caching
Store gets loaded for every update, even though it's already in RAM elsewhere, so repeated updates on same store thrash it.
How to fix?
I had an initial go at this but it the logic at present is too complex so had side effects which made things worse.
We need a better way to deal with this. Notionally we need a second cache for writes, which works in the same way as for reads. The existing
updateref
mechanism or something similar is still required so we know when a store is locked.It might be appropriate to use a wrapper class, e.g.
StoreRef
, for all store updates so reference-counting happens in the constructor/destructor. This may supplement or replace use ofshared_ptr
.Test log
Here's the log which shows the problems: