Click here to Skip to main content
15,892,059 members
Articles / Programming Languages / C#

A Fast/Compact Serialization Framework

Rate me:
Please Sign up or sign in to vote.
4.85/5 (37 votes)
13 Oct 2010GPL35 min read 283.3K   1.2K   175  
A framework for object serializiation/deserialization that is many times faster and yields a compact output.
/*

OpenNxSerialization Framework
Copyright (C) 2006 - 2008 "NeXtreme Innovations"
[The Next Xtreme Innovations]

This program is free software, distributed under the terms of
the GNU General Public License Version 2. See the "License.txt" file
at the top of the source tree.

*/
using System;
using System.Collections;
using System.Configuration;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

using NeXtreme.OpenNxSerialization;
using NeXtreme.OpenNxSerialization.Formatters;
using NeXtreme.OpenNxSerialization.Surrogates;
using NeXtreme.OpenNxSerialization.IO;
using NeXtreme.OpenNxSerialization.Configuration;

using NeXtreme.CommonTypes;
using NeXtreme.CommonTypes.Utility;
using NeXtreme.Benchmark.Properties;

namespace NeXtreme.Benchmark
{
    /// <summary>
    /// The main entry class for the application.
    /// </summary>
    partial class Program
    {
        static readonly int kIterations = Settings.Default.NumIterations;
        static readonly int kRunCount = Settings.Default.RunCount;

        static Profiler nstats = new Profiler(1, 10);
        static Profiler cstats = new Profiler(1, 10);

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main(string[] args)
        {
            Configure();
            RunBenchmarks();
        }

        private static void RunBenchmarks()
        {
            // NxSerialization.Benchmark sample struct containing float members
            DoBenchmark(new DataPoint());

            // NxSerialization.Benchmark simple enumeration
            DoBenchmark(SampleEnumeration.Three);

            // NxSerialization.Benchmark simple int array
            DoBenchmark(new int[256]);

            // NxSerialization.Benchmark simple int array
            Hashtable hashtable = new Hashtable();
            hashtable[0] = new Guid[32];
            hashtable[1] = hashtable[0]; hashtable[2] = hashtable[1];
            hashtable[3] = new Guid[32];
            hashtable[4] = hashtable[3]; hashtable[5] = hashtable[4];
            DoBenchmark(hashtable);

            // Perform shared reference test!
            Console.ForegroundColor = ConsoleColor.Red;
            Hashtable htClone = (Hashtable)DeepClone(hashtable);
            Console.Write("Shared reference test ");
            Console.WriteLine(Object.ReferenceEquals(htClone[0], htClone[1]) ? "passed!\r\n" : "FAILED\r\n");
            Console.ResetColor();

            // NxSerialization.Benchmark nullable int array
            int?[] nullablesArray = new Nullable<int>[100];
            for (int i = 0; i < nullablesArray.Length; i += 1)
                nullablesArray[i] = i;
            DoBenchmark(nullablesArray);

            // NxSerialization.Benchmark simple INxSerializable class
            // Implicitly performs circular reference test!
            DoBenchmark(new SampleParentClass());

            // NxSerialization.Benchmark simple INxSerializable class
            SampleParentClass[] sampleParentClassArray = new SampleParentClass[100];
            for (int i = 0; i < sampleParentClassArray.Length; i++)
                sampleParentClassArray[i] = new SampleParentClass();
            DoBenchmark(sampleParentClassArray);

            // NxSerialization.Benchmark simple SampleINxSerializableClass class
            DoBenchmark(new SampleINxSerializableClass("SampleINxSerializableClass"));

            // NxSerialization.Benchmark ISerializable class
            DoBenchmark(new NativeButCustom());
        }

        /// <summary>
        /// Perform time and space comparisons.
        /// </summary>
        private static void DoBenchmark(object sampleGraph)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("----------------------------------------------------");
            Console.WriteLine();
            Console.WriteLine("Benchmarking type -- {0}", sampleGraph.GetType().FullName);
            Console.WriteLine();
            Console.ResetColor();

            CompareMemoryRequirements(sampleGraph);
            nstats.Measure(kIterations, kRunCount,
                delegate
                {
                    byte[] arr = NativeSerializationHelper.ToByteBuffer(sampleGraph);
                    NativeSerializationHelper.FromByteBuffer(arr);
                }
            );
            cstats.Measure(kIterations, kRunCount,
               delegate
               {
                   NxBinaryFormatter formatter = new NxBinaryFormatter();
                   byte[] arr = formatter.ToByteArray(sampleGraph);
                   formatter.FromByteArray(arr);
               }
            );

            Console.WriteLine();
            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.WriteLine("Time Native serialization = {0}", nstats.Total);
            Console.WriteLine("Time Compact serialization = {0}", cstats.Total);
            Console.WriteLine("Performance = {0:F2}% less time, {1:F1} times faster.",
                100 - (float)cstats.Total / (float)nstats.Total * 100,
                (float)nstats.Total / (float)cstats.Total);
            Console.ResetColor();

            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine();
            Console.WriteLine("Native serialization statistics...");
            Profiler.PrintExtended(nstats);
            Console.WriteLine("Compact serialization statistics...");
            Profiler.PrintExtended(cstats);
            Console.WriteLine();
            Console.ResetColor();
        }

        /// <summary>
        /// Compares the sizes of resulting streams.
        /// </summary>
        static private void CompareMemoryRequirements(object graph)
        {
            NxBinaryFormatter formatter = new NxBinaryFormatter();
            byte[] arr = NativeSerializationHelper.ToByteBuffer(graph);
            byte[] arr2 = formatter.ToByteArray(graph);

            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine("Stream size Native serialization = {0}", arr.Length);
            Console.WriteLine("Stream size Compact serialization = {0}", arr2.Length);
            Console.WriteLine("Compression = {0:F2}% less space, {1:F1} times compact.",
                100 - (float)arr2.Length / (float)arr.Length * 100,
                (float)arr.Length / (float)arr2.Length);
            Console.ResetColor();
        }

        static private object DeepClone(object graph)
        {
            NxBinaryFormatter formatter = new NxBinaryFormatter();
            byte[] arr = formatter.ToByteArray(graph);
            return formatter.FromByteArray(arr);
        }
    }


    internal class NativeSerializationHelper
    {
        static BinaryFormatter formatter = new BinaryFormatter();

        /// <summary>
        /// serialize an objevt into a stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="objectToSend"></param>
        public static void Serialize(Stream stream, object objectToSend)
        {
            formatter.Serialize(stream, objectToSend);
        }

        /// <summary>
        /// deserialize an object from the stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public static object Deserialize(Stream stream)
        {
            return formatter.Deserialize(stream);
        }

        /// <summary>
        /// Creates an object from a byte buffer
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static object FromByteBuffer(byte[] buffer)
        {
            if (buffer == null) return null;
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                return Deserialize(ms);
            }
        }

        /// <summary>
        /// Serializes an object into a byte buffer.
        /// The object has to implement interface Serializable or Externalizable
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static byte[] ToByteBuffer(object obj)
        {
            if (obj == null) return null;
            using (MemoryStream ms = new MemoryStream())
            {
                Serialize(ms, obj);
                return ms.ToArray();
            }
        }
    }


}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Architect
Pakistan Pakistan
Let a = b ....... (1)
a - b = a - b
a^2 - ab = a^2 - ab
a^2 - ab = a^2 - b^2 (from 1)
a (a - b) = (a + b) (a - b)
a = (a + b) ...... (2)

if a = 1
1 = (1 + 1) (from 1 & 2)
1 = 2 !!

Comments and Discussions