DataSet och binärserialisering i .NET FX 2.0

Under ett av våra seminarier så uttryckte jag mig lite luddigt kring storleken på data i ett DataSet när det serialiseras och blev ombedd att reda ut det lite mer utförligt vilket jag nu ska försöka göra.

Det som har hänt med .NET FX 2.0 är att vi har fått en möjlighet att serialisera DataSet till binär form "på riktigt" i jämförelse med tidigare ramverk. Tittar man på koden nedan som visar den enda vägen som fanns tidigare så innebär det att DataSet:et kommer att först serialiseras till en XML-sträng för att sedan kunna sparas ner i en fil i binär form. Vi drar alltså ingen nytta av att spara ner vårt data till binär form direkt för att få mindre volym på det serialiserade datat och även bättre prestanda vid deserialisering.

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(SQL, connect);
da.Fill(ds);

// create BinaryFormatter and Stream
IFormatter f = new BinaryFormatter();
Stream s = new FileStream("standard-format.dat", FileMode.Create, FileAccess.Write, FileShare.None);

// write contents of DataSet to Stream
f.Serialize(s, ds);
s.Close();

Det som hänt med ramverk 2.0 är att vi fått en möjlighet att sätta hur vi vill att ett DataSet ska serialieras. Genom att sätta egenskapen "RemotingFormat" till "Binary" kommer vi att hoppa över steget med serialisering till en XML-sträng först och istället gå direkt på att spara ner vårt data i binär form. I koden är alltså endast en enda rad ändrad.

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(SQL, connect);
da.Fill(ds);

// now specify Binary remoting format for the DataSet
ds.RemotingFormat = SerializationFormat.Binary;

// create BinaryFormatter and Stream
IFormatter f = new BinaryFormatter();
Stream s = new FileStream("standard-format.dat", FileMode.Create, FileAccess.Write, FileShare.None);

// write contents of DataSet to Stream
f.Serialize(s, ds);
s.Close();

Fördelen med detta är att serialisering/deserialisering kommer att gå snabbare men framförallt så kommer storleken på det sparade datat att minska avsevärt då vi inte kommer ha XML-taggar som separatorer för de olika datafälten.

I min presentation använde jag ordet "exponentiell" vilket var lite galet, det jag menade var att storleken avtar starkt med en ökad storlek av antalet rader i DataSet:et som ska serialiseras om man använder binär form istället för "ren text". Nedan är en tabell med storleken i procent för binärserialisering av den i XML-form.

Rader i DataSet Storlek i %
100 35
1000 4
10000 2
100000 1

Nu är inte detta exakta siffror utan är beroende av hur många kolumner varje rad har och hur stora dessa är men det ger en fingervisning om att storleken minskar drastiskt med antalet rader.

Förträffligheten med detta är kanske inte främst möjligheten att spara diskutrymme utan snarare vid överföring av data över nätverk då mindre data innebär snabbare överföringstider och därmed förhoppningsvis också snabbare svarstider i applikationer.

Ser man till vad egenskapen på DataSet:et heter, "RemotingFormat" så inser man snabbt att detta är delvis tänkt att användas vid just "Remoting".