Performance And Comparison

Zohaib Sibte Hassan edited this page Mar 27, 2016 · 3 revisions

Disclaimer

This article in no way suggests you to dump SQLite or any other database and start using LevelDB. The sole intent of this article is to compare other production ready databases to LevelDB UWP port. Following assumptions (covers 90% of the apps) were taken while benchmarks were being performed:

  • Mobile apps don't store a lot of data (1K - 15K tuples are usually enough).
  • Applications are usually single process (LevelDB has no multi-process support).
  • Data tuple has been approximated to 4KB - 7KB per entry which is a decent size for a normal twitter entry. It's not perfectly random but it doesn't give LevelDB any advantage over others.
  • No compression was used on LevelDB to make sure everyone writes same amount of data.
  • Each entry written from LevelDB is synced to disk before it returns true. So nothing is in memory when a write takes place!

The setup

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). 

Results

Given above rules and assumptions here are the benchmark results:

Random Inserts

Random Inserts

Random Reads

Random Reads

Random Deletes

Random Deletes

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:

Conclusion

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.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.