Storage for Windows Phone 7 is an important issue and needed for both supporting tombstoning by persisting state and for storing application data.
The out of the box storage mechanism available on the phone is IsolatedStorage, accessible either via an class library with classes such as IsolatedStorageFile and IsolatedStorageFileStream, or through a key-value store accessible via IsolatedStorageSettings.ApplicationSettings. The latter is intended for low volumes of data only, and the entire key-value store is loaded into memory when it is accessed the first time.
An interesting project is Sterling Isolated Storage Database with LINQ for Silverlight and Windows Phone 7, available at http://sterling.codeplex.com/. As the name reveals, it’s a database that hides the internals of IsolatedStorage and gives you a LINQ interface. Other features include caching, indexing and logging.
Quick intro to Sterling
Getting started with the database is really easy, the four steps described in the Sterling Windows Phone 7 documentation is spot on and provides a ready-to-use database. The documentation shows the bootstrapping code, creation of a singleton in App.xaml.cs and the usage of the DB instance.
Just to show you what some of the code looks like, here is first the bootstrapping, where Contact is your custom class:
//in ContactDatabase : BaseDatabaseInstance
CreateTableDefinition<contact, int>(i => i.Id)
_database = _engine.SterlingDatabase.RegisterDatabase<contactDatabase>();
Adding to the database is as easy as:
Reading all contacts:
foreach (var item in App.Database.Query<contact, int>())
Now – to the performance test!
In a recent project I used IsolatedStorageSettings.ApplicationSettings as only storage – which is a big no-no but actually turned out quite fine! The app didn’t have that much data though. As I mentioned earlier, the entire IsolatedStorageSettings (ISS) store is loaded when it’s accessed the first time. To have a fair comparison, I’ve created a small test app that reads and writes 100 items. Each item is a simple class with 5-6 strings, a bool and an int. Contestant A is the ISS store, contestant B is the Sterling database. A very good comparison of serialization methods has been done by Kevin Marshall, with example app.
The ISS store in this example uses JSON to serialize the items into a string for storage, according to what I’ve read about Sterling, it uses binary serialization internally, I am not entirely sure though.
I also have not examined the size of the data in isolated storage, I assume that the Sterling database with data is smaller in size than the JSON data.
Tests, starting with a fresh installation of the app.
|1. Store 100 items||156 ms||15503 ms|
|2. Store an additional 100 items||121 ms||8471 ms|
|3. Read all items (200)||593 ms||2062 ms|
|4. Read all items again||597 ms||0 ms|
|Restart the app|
|5. Read all items (200)||766 ms||2109 ms|
|6. Read all items again||604 ms||1 ms|
|Reinstall the app|
|7. Read all items (0 items)||44 ms||3 ms|
|7. Read all items (0 items)||0 ms||0 ms|
I am very surprised by the results! Even though Sterling is an extremely competent database with a bunch of convenient features, I did not expect it to be so slow.
Comments on the actions performed
Action 1,2: Both systems seem to have init-time
Action 3,4: Here Sterling shines, built-in caching – nice!
Action 5,6: “Cold start” performance is about the same as warm, except for ISS that has to do load the data in action 5.
Action 7,8: Sterling apparently has no init-time if the DB is empty, nice.
If you want to store a lot of data and/or have advanced scenarios – do check out Sterling, but monitor performance. It’s still beta but a very nice project.
I added my custom code to the official Sterling example project, build 0.9.0.0 was used.
Tests were conducted on a Samsung Omnia 7.