Note: this entry has moved.
In the following post I’m going to focus on the new viewstate serializer exclusively; keep in mind that there are other strategies being introduced in order to reduce viewstate size, like separation between viewstate as we know it today and a new control state.
Also, when using the term “serializer” I’m referring to the viewstate serializer unless otherwise noted.
New added support for common types
As I mentioned in a previous post, the serializer in ASP.NET v1.x was designed to handle only a few different types and it is not really a good idea to feed it with anything else.
In Whidbey, the serializer is being extended to support 10 additional types: IndexString, byte, char, DateTime, double, short, float, HybridDictionary, Enum and Color meaning that all these types now generate smaller footprints.
Aside from supporting new types, current serialization is being optimized. Let’s see some of the introduced changes.
Clever Gets Clever: type code = type + state
How is a Boolean handled? In v1.x they decided this was a very common type and added support for it into the viewstate serializer. This support means having a dedicated type code that represents a Boolean type thus avoiding the need to persist any additional extra information in order to properly identify it and de-serialize it later on.
This is how a serialized Boolean looks like in v1.x:
111 – code representing a Boolean type
60 – token representing the beginning of the stored state
116 or 102 – only one is used, depending on the instance value being true or false respectively.
62 – token representing the end of the stored state
Thanks to this type code optimization the footprint ends up being of 4 bytes which –believe it or not- is not that bad when compared for example to the footprint that would have been generated by the BinaryFormatter itself (~27 bytes).
First thing to notice in Whidbey is the reduction of token usage (char 60 and 62). In my opinion this “tokenized” approach of v1.x was largely useless so it’s a good thing to know it changed. Ok… so that’s two bytes shorter for a start.
Second thing we can see in Whidbey is that now the Boolean type code represents type plus state. Having two possible states bring us two different type codes: 104 for a Boolean with a value of false and 103 for a Boolean with a value of true. This means one less byte, which including the previous reduction, totals three less bytes, a 75% reduction, not bad. This is how a Boolean with a value of true looks like when serialized by Whidbey’s viewstate serializer:
103 – code representing a Boolean set to true
We miss you, Unit
There is a notoriously lack of support for the System.Web.UI.WebControls.Unit type in Whidbey.
In v1.x this type was assigned its own type code (49) which saved the serializer from having to store an –often large– string representing its assembly-qualified name.
In Whidbey, Unit is not backed up with a type code meaning that its full type name (yes, its full name and not its assembly-qualified one, wait till next title to learn why!) needs to be stored into viewstate, which means storing once the following additional string:
None of the two serializers, the v1.x and the Whidbey one, do support any special serialization for this type; it’s being handled by a UnitConverter.
How this absence of a type code for Unit in Whidbey ends up reflecting in the final footprint?
Let’s take for example the following Unit instance:
Unit u = new Unit (“100px”);
In v1.x this instance will end up serialized into 8 bytes while in Whidbey final footprint will be of 39 bytes. Ugly… I know.
Types from System.Web.dll assembly are loved (and around 82 bytes cheaper now!)
In v1.x, non-optimized types were handled down to a type converter when available. When this happens the assembly-qualified name of the type needs to be stored into viewstate which is not fun at all as it usually tends to be a quite large strings, i.e.:
System.Web.UI.WebControls.Unit, System.Web, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
In Whidbey, the serializer performs an additional check and if its dealing with a type that lives in the System.Web.dll assembly then it uses a special code (42) to signal it so only the full name of the type needs to be saved, i.e.:
This avoids the need for having to store assembly-qualified names for any non-optimized types living in System.Web.dll assembly which will usually result in saving ~82 bytes of storage caused by the following string:
System.Web, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
There are other interesting things going on about the new serializer, like the special treatment some types as Color are given in order to produce the smaller possible footprint. I guess I will save them for a later post…