I got email from Richard suggesting the ViewState storage could be improved if string lengths were stored in a compact form to optimize for the mainline short string scenario. It turns out this is already the case. I described most of the optimizations in an older post on view state improvements.
The thing to keep in mind is that the ASP.NET Development Helper shows decoded view state and not the optimizations, which might have raised the question. The job of the formatter is to hand back the same object graph that it was passed in; the optimizations happen behind the scenes. This got me thinking about creating a view over the token stream itself. After some experimentation, I updated the tool to also provide a visualization of the compacted form that shows what each byte in the blob represents. The image below shows the decoded view state tree on the left (actual state), and the token tree on the right.

The code used to generate this state is:
void Page_Load() {
object[] state = new object[8];
state[0] = new Pair(new IndexedString("abc"), 123);
state[1] = new Pair(new IndexedString("abc"), true);
ViewState["MyProp"] = state;
}
This screenshot allows me to describe a new optimization added in Beta 2 after my initial post - specifically the "sparse array" optimization. Notice in the actual state tree, there is an array containing 8 items of which 6 items are null. The token tree though contains a special token which stores count of items, and count of non-null items, followed by just the non-null items, when an array has fewer slots filled than a certain threshold. While not immediately apparent, this pattern occurs quite frequently: a Panel with many of child controls of which just one has non-null view state, a complex control like GridView which has multiple stateful properties (styles etc.), of which only one property was changed etc.
Also note another optimization where the second IndexedString is saved as simply as a reference into a string table as described earlier. So the token stream contains the string just once, even though the actual data tree contains two string instances.
ObjectStateFormatter essentially converts a state graph into a stream of tokens:
- Serializer tokens: Meta-information such as version information.
- Control tokens: Indicate the nature of the next set of following tokens.
- Metadata tokens: Metadata about actual content (eg. array length).
- Content tokens: The actual content itself.
The updated development helper tool will show this tree, and also shows the byte size of each token, as well as the size of the token and its subtree - Exactly the kind of information needed if you want to squeeze some bytes out of your control's view state usage.
The ObjectStateFormatter is used for other things such as the default WebPart personalization storage format (should explain the version token). In fact, the next version of the development helper tool also uses this mechanism to transfer data. The updated tool will be available soon...
Posted on Wednesday, 5/18/2005 @ 11:57 PM
| #
ASP.NET