Database cache size
Disk access is orders of magnitude slower than memory access so the size of the cache has a big impact on Volante performance. Default size of the cache is 4 MB. You can change the cache size by providing
cacheSizeInBytes argument to
IDatabase.Open() call. Don't make it smaller than 64 kB.
A bigger cache usually leads to faster operations, but keep the following in mind:
- a very large cache might cause your application to use all available memory which might lead to disk swapping which will drastically degrade the performance of the whole system, including your application
- operating system also maintains file cache, so data is cached twice. That being said, accessing data from cache is faster than from operating system cache because we avoid overhead of OS call and context switching
- it's not possible to have zero-sized cache. When data is accessed it has to be pinned in the cache so the cache should contain enough entries to keep all pinned pages. Don't make the cache less than 64kb
You can use Volante as an in-memory database by passing
Using larger transactions
Larger transactions (calling
IDatabase.Commit() less frequently) also improve performance and reduce the size of the database file.
Volante uses shadow objects for changed (but not yet commited) data. If you change the object multiple times, it's cheaper to commit only once after several changes than commit several times, after each change.
Volante groups objects into 4kB pages and reads/writes a whole page at a time. Changing only one object causes a whole page to be modified so it's cheaper to group modifications to minimize number of changed pages.
The disadvantage of larger transactions is that in case of a crash more data will be lost.
Be careful about your in-memory object graph
Usually the database root object is kept in some variable during the lifetime of your program. That means that root object and all of the objects it points to will not be reclaimed by .NET garbage collector. If anywhere in your graph you reference a large number of objects e.g. as
IPersistent largeArray, all of them will be kept in memory all the time.
Not flushing file buffers
When Volante writes its data to a file, by default it flushes file buffers (i.e. calls FlushFileBuffers() win32 function). This is needed for reliability, to make sure that the data has really been written to disk and not merely queued by the operating system for writing. This is slower than not flushing. If you can sacrifice reliability, set
IFile.NoFlush property to
This only affects
IFile implementations that write to disk, like
Tuning datbase parameters
The following properties on
IDatabase influence performance. If changed, they should be set before the database is opened. The values are in bytes.
||1024||Initial size of the object index. Object index is increased on demand. Reallocation of index is expensive. To minimize number of reallocations, object index size is always doubled. Larger initial index size will reduce number of future reallocations which will slightly increases performance. It will also lead to a larger initial size of database file. With default value of this parameter, initial database size is about 50Kb.|
||4Mb||Memory is allocated by scanning bitmap. If a big enough space cannot be found, the database is extended by the value of|
||1319||Volante needs object cache to check if an object with a given oid is already loaded in memory. This cache uses weak references to allow garbage collector to reclaim memory used by objects. When a cache fill threshold is reached, cache is reallocated by doubling its size. Increasing this parameter can save cache reallocations, which leads to higher performance but also higher memory use.|
Using code generation
Volante is using its own serialization/deserialization which happens every time an object needs to be stored in the database or loaded from the database. This happens often.
To speed up serialization/deserialization Volante can dynamically generate optimized methods for serializing each type (as opposed to using a slower, generic method).
To enable that set
IDatabase.CodeGeneration property to
A small downside is that those functions have to be generated every time a database is opened, which might slow down opening of the database if it contains a lot of types.