Show HN: LevelDB outperforms others on a cheap phone (Microsoft ESE and SQLite)
github.com
github.com
I would love to see the article updated using SQLite's PRAGMA journal_mode = WAL and PRAGMA synchronous = NORMAL. Then it would be a much more fair comparison.
Please don't give programmers a license to be lazy and not learn about their tools!!! If this article is trying to inform, or give benchmarks, it should not come to invalid conclusions without explaining the tradeoffs.
Considering your background and endorsement of nosql databases, it comes off as more of a puff piece if you don't actually try to make the other db's run fast. It especially seems that way when you tout it as "blazing fast compared to any other storage solutions", and then proceed to test it in one narrow setup.
That noted, you said that you used the default settings, and I'd be curious if there are settings for LevelDB that could be changed to make it faster.
I'd be interested if you did more tests explore more than just one particular setup.
Edit: I realized that this may have come off a little negative. Overall I think it's nice, but seems less applicable than you make it seem.
Comparing it to levelDB is like comparing redis to postgres with default value.
You can use postgres as redis. You can actually use the key/value store engine and tweak the settings to get very nice performance out of it. But it's not the default behavior.
I always like reading comments on these types of analyses, since they often use the author's data to help me understand what might have been overlooked (which I often would have overlooked also!).
https://www.usenix.org/conference/atc13/technical-sessions/p...
SQLite 4 is supposed to have a simplified K/V storage engine. That would probably be a more fair comparison.
(Hm, looking at LevelDB I don't see references to Android any more, maybe they dropped support?)
SQLite 4 looks pretty darn cool, is it still actively being worked on? Commits seem quite scarce[2].
--
For those who don't know, I/O on Android is a nightmare. On your typical phone, the filesystem you have access to is a FUSE that mirrors to an EXT4 filesystem mounted with crazy device-specific options which include noauto_da_alloc.
I don't know any DB which works fast and consistently across all Android phones on the market. SQLite is probably the safest bet for now.
How is that possible if they are using Linux and UBC (Unified Buffer Cache). It's unlikely they anybody would go undo that from the VM/FS layer.
The only think I can think off this behavior happening in a Linux app is if you're creating a private mapping... Private mappings are COW and a write to the global would cause a copy of the old data for you app. They'll be no sycing till you msync()
While trying to debug I ended up on the only question ever asked by Howard Chu (LMDB author) on Stack Overflow: http://stackoverflow.com/questions/7061910/when-does-an-o-sy...
I am still trying to figure out what exactly is happening here but it's not very easy given that I do not even have access to a rooted phone that exhibits the issue.
Here's the code that resulted from that Stack Overflow question: https://github.com/LMDB/lmdb/blob/mdb.master/libraries/liblm...
After 36 years of writing code, I have more answers than questions.
LMDB has been tested on quite a lot of filesystems, not just ext.
http://symas.com/mdb/microbench/july/#sec11
And actually, LMDB was working fine back in the Froyo/Gingerbread days. I integrated it into XDAndroid way back then. http://forum.xda-developers.com/showthread.php?t=1171052 (By way of SQLightning.)
Never tested it on things like squashfs or whatnot though.
The performance numbers are actually mediocre at best in "real world" conditions. When I tried using it in a project where both high performance and concurrency were needed, I also discovered that it doesn't scale past 1 CPU core - probably uses mutexes or inefficient locks. I gave up on it rather than trying to fix it.
That said, it has a simple API and sometimes neither concurrency nor ACID are important.
Also, I'd argue leveldb shines in a distributed environment where the simple interface is easy to leverage at scale--after all, it is basically the tablet part of big table.
"By default, each write to leveldb is asynchronous: it returns after pushing the write from the process into the operating system. The transfer from operating system memory to the underlying persistent storage happens asynchronously. The sync flag can be turned on for a particular write to make the write operation not return until the data being written has been pushed all the way to persistent storage. (On Posix systems, this is implemented by calling either fsync(...) or fdatasync(...) or msync(..., MS_SYNC) before the write operation returns.)"
and if you see my benchmarks I am flushing each entry to the disk.
btw I've had better experience using kyoto db than levelDB.
It's not about intensive reads/writes (dozens of MB) it's about making each individual read or write very fast so you don't drop frames. On Android you have 16ms to draw each frame (60fps). If you have a DB request take 5ms then all of a sudden you're very likely to have jank in your app.
But any well architected app that wants to work well without Internet will write many things to disk.
500 writes a second is very realistic when downloading some bulk content that will be used to power different states of the app. Now this might not be a continuous burst of 500 operations a second sustained, but many it has a handful of these bursts over several minutes. Given that, I would say that lots of mobile apps can have brief periods of tons of writes.