This is a bit of a techy post so if you’re not into the geeky codey stuff, skip over it!. 🙂
For the last few days I’ve been working on the WP7 version of Fizz Filler. All was going fine, except every time the game saved, it would freeze for around 20 seconds.
I’ve spent since yesterday afternoon trying to find the reason behind this freeze, until finally throwing in a bunch of stopwatch timers to figure out which part of the saving code was slowing it down.
Low and behold, it turned out to be the most unexpected of them all.
For some unknown reason on WP7, it takes this single property a good 30 – 50ms to return a value, despite being as speedy as a usual on WP8.
The main part of my saving code uses a custom made class where data is written in a Key-value structure, which means each piece of data has a friendly word associated with it to make it more readable.
The part where the slowdown happened was where I had 3 calls to the above code for each Key-value that was saved as part of my error-checking code, which allowed a piece of data to be skipped if it was corrupt or incorrectly saved.
Heres the C# code that handled writing of key-value data in my KeyValueStorage class.
public void Write(BinaryWriter writer)
object value = null;
long writeStart = writer.BaseStream.Position;
writer.Write(_values.Count); //write initial count -- come back later and finalize it if needed
int intSize = sizeof(int);
int valueCount = _values.Count;
foreach (string key in _values.Keys)
value = _values[key];
Type inputType = value.GetType();
TypeProcessor processor = null;
//try to find a processor for the type -- if one isn't found, skip the key-value entirely
if (TypeProcessor.GetProcessor(inputType, out processor))
long startPos = writer.BaseStream.Position;
//skip intSize number of bytes to leave somewhere to write the number of written bytes once done.
//write the key name
//write the type of the object being stored
string tName = LeafHelper.GetTypeString(inputType);
//figure out how many bytes were written
long endPos = writer.BaseStream.Position;
int written = (int)(endPos - startPos);
//seek back to before all the data was written and store the number of written bytes.
//go back to the end of the data that was written, ready to write the next.
writer.Seek(written - intSize, SeekOrigin.Current);
//correct the value count if needed
if (valueCount != _values.Count)
long prevPos = writer.BaseStream.Position;
//return to the end of the stream
As you can see, 3 calls are made to writer.BaseStream.Position (4 if something goes wrong), where BaseStream is an IsolatedStorageStream instance. If each call takes around 40ms to execute, it soon adds up to around 120ms to write a single key-value. Fizz Filler stores a large amount of these values, around 170 of them. So that adds up to around 20700ms (20.7 seconds), which not even remotely acceptable/playable for a game!
For now, I’ve sort of fixed it the dirty way on WP7 by disabling all of the error-checking code, so that it doesn’t need to make any calls to the slow position property. But later, I’ll be solving the problem cleanly by first making it write to a memory stream, then grabbing the size of the data that was written from that, before finally writing it to your phone’s storage.
A memory stream works the same way as a storage or file stream, except instead of writing to your phone’s storage, it writes into your phone’s memory, which is much, much faster, but not permanent. So this is great if you want to prepare data (or get the size of it!) before finally storing it on the phone properly.
If all goes well, this will mean no more slow down, while I still get to keep the error-checking stuff on both WP7 and 8. 🙂