LevelDB is blazing fast compared to any other storage solutions available on UWP. It's not just a claim; here is a sample application try it yourself. I compared it with almost all famous free solutions out there, list includes:
- SQLite 3 - needs no introduction, a really well known option in Universal Windows community. I chose the most used SQLite-Net PCL library for sake of this comparison.
- Lex.DB - a lesser known storage option written completely in C#, hence works across several platforms without any complicated compile processes. It also provides really clean ORMish API.
- Microsoft's ESE - has been around for ages but less used than SQLite. It's based on Jet Blue (not Jet Red) engine; it's used extensively in Microsoft Exchange and Active Directory. There is a ManagedESENT wrapper, but requires boilerplate code for writing trivial key-value store (checkout source code you will see what I mean).
For keeping data as close to real as possible the project downloads an RSS feed. These feed entries are then selected at random, with unique key and then inserted. Hence the entries are inserted in random order. Each entry is 4KB to 7KB. Keep in mind all of the stores mentioned here keep entries sorted by keys. Here are the rules that I am following when testing for performance:
- Changes written to the store are flushed immediately. This means we don't do any kind of batching over the data; no SQLite transactions, No LexDB batches and no ESE batches etc.
- Read/Writes are in random order (usually all stores get a performance hit with random keys), sequiential reads/writes in LevelDB are known to be faster . Idea over here is to take away the LevelDB's sequential read/write advantage.
- Apply same serialization and deserialization overhead to each respective library, in case of LevelDB I am using JSON to serialize the complete object. SQLite, ESENT goes through same JSON serialization/deserialization. LexDB gives an out of box object serialization/deserialization system.
- Read and Delete in same random order, so the pattern here is I am not going for sequential stuff at all.
- For sake of persistence and not relying on any store particular for storing keys, I serialize all the keys as JSON in a plain text file. This keeps any store from warming up cache or anything.
- Run tests on worst possible configuration! I was able to get my hands on Lumia 630 (running Windows 10) + SD card (The phone has only 512MB of RAM and it's one of the super low-end devices).
- Code is compiled to .Net native to ensure best code performance.
Some of you might object about the nature of stores being used in comparison, all of them can serve as full fledged storage and retrieval system (with secondary index support, relations etc.). LevelDB is just a trivial Key-Value store. When compared to LevelDB every store provides more features. I am not using any of those sophisticated features and I am using all of them like what a typical programmer might have done if he/she had to pick one of them as a key-value store. One can obviously write a more sophisticated layer on top of LevelDB (I have already started off a project for doing so ).
Given above rules and assumptions here are the benchmark results:
Results are mind boggling! LevelDB takes only fraction of IO and time compared to other stores. Results given above are just for 500 entries, as you increase number of entries the performance gap increases even more. Checkout results for 1000 entries:
LevelDB out performs most of Key-Value stores out there. Due to it's modern LSM implementation it's an ideal choice for applications doing intensive reads/writes.