In a current GlobalLogic project, we are managing a 3MB database in SQLite running on Android. As a data-intensive application, SQLite has performance challenges, so we were looking for an alternative. Fortunately, a nicely crafted persistent layer allowed us to change the underlying storage mechanism. One option was to use Realm, a mobile database that is faster and easier to use. Although still under development, it is loved by many developers and users worldwide.
This is a high-level introduction to Realm.
What is Realm?
Unlike SQLite, Realm is a mobile first database engine, built from scratch using C++ core. It stores data in a universal, C++ core table-based format. Realm is an open-source, object-oriented database, built specifically for mobile devices, keeping in mind mobile device constraints (compared to desktop). The key difference between Realm and other object-oriented databases is that the objects are stored in a language-independent format. This hybrid object/table approach has an advantage over a relational database, because it allows efficient graph querying—of even deeply nested object graphs on relatively older smartphones—without impacting response times.
Benchmarks published by Realm claim, on average, up to a 10x increase in speed over raw SQLite for normal operations. Our tests have shown a huge performance gain for read operations and 20% to 50% improvement for data manipulation operations, as shown in the graphs below.
Why is Realm so fast?
Traditionally object retrieval from an ORM/RDMS involves data copying and serialization/deserialization when data passes through different layers (language to database to language). Realm skips this entire process as the database file is always memory mapped. Realm accesses any offset in the file as if it were already in memory, even when it’s not, since it’s virtual memory. This is an important design decision for the core Realm file format. It allows the file to be readable in memory without having to do any deserialization. It simply calculates offsets to find data in the file and returns that value from the raw accessors on the data structure. This is much more efficient and therefore much faster.
Relationships in Realm are also extremely fast because indexes traverse a Btree-like structure to the related object. This is much faster than querying, because there is no need to perform another full query. It is simply a native pointer to the related object.
Making development easier
In addition to performance, Realm saves you from writing entire database plumbing code. As a developer, you deal with objects rather than database tables. The database operations code size is virtually zero.
Accessing Realm from a background thread looks the same as accessing Realm from the UI design services thread. There is no need to maintain multiple contexts and merge them manually, no inconsistent views, and no headaches trying to reconcile your data. The only limitation is that object instances cannot be passed across threads, meaning you cannot have one thread for fetching the data and then passing it to another thread (probably a UI thread) for further processing. Realm provides its own APIs for this asynchronous behavior. You just need to register call backs to read the data from the API.
Realm has built-in support for encryption using AES-256+SHA2. There is a small performance hit (typically less than 10%) with encrypted Realms.