/*
OpenNxSerialization Framework
Copyright (C) 2006 - 2008 "NeXtreme Innovations"
[The Next Xtreme in ingenuity]
This program is free software, distributed under the terms of
the GNU General Public License Version 2. See the License file
at the top of the source tree.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using NeXtreme.OpenNxSerialization;
using NeXtreme.OpenNxSerialization.Surrogates;
using NeXtreme.OpenNxSerialization.IO;
using NeXtreme.OpenNxSerialization.Configuration;
using NeXtreme.OpenNxSerialization.Native;
using NeXtreme.OpenNxSerialization.Native.Formatters;
using NeXtreme.OpenNxSerialization.Dynamic.Surrogates;
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;
private static bool mTabularStats = true;
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()
{
ArrayList list = new ArrayList();
list.Add(new Char());
list.Add(new Int32());
list.Add(new Int64());
list.Add(new Double());
list.Add(new DateTime());
list.Add("Hello World!");
list.Add(new Guid());
list.Add(SampleEnumeration.Three);
list.Add(new byte[100]);
list.Add(new Char[100]);
list.Add(new Int32[100]);
list.Add(new Int64[100]);
list.Add(new Double[100]);
list.Add(new DateTime[100]);
list.Add(new String[100]);
// OpenNxBenchmark nullable int array
int?[] nullablesArray = new Nullable<int>[100];
for (int i = 0; i < nullablesArray.Length; i += 1)
nullablesArray[i] = i;
list.Add(nullablesArray);
list.Add(new Int64?[100]);
list.Add(new Double?[100]);
// OpenNxBenchmark 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];
list.Add(hashtable);
// OpenNxBenchmark sample struct containing float members
list.Add(new DataPoint());
// OpenNxBenchmark simple INxSerializable class
list.Add(new CustomNxSerializable());
// OpenNxBenchmark simple INxSerializable class
CustomNxSerializable[] sampleParentClassArray = new CustomNxSerializable[100];
for (int i = 0; i < sampleParentClassArray.Length; i++)
sampleParentClassArray[i] = new CustomNxSerializable();
list.Add(sampleParentClassArray);
// OpenNxBenchmark simple SampleINxSerializableClass class
list.Add(new SampleINxSerializableClass("SampleINxSerializableClass"));
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("Running bencmarks with {0} iterations and {1} runs per iteration...", kIterations, kRunCount);
Console.WriteLine();
// Run Memory Benchmarks
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Memory Comparison");
Console.WriteLine("-----------------------------------------------------------");
if (mTabularStats)
{
Console.Write("{0,10}, ", "Mem .NET");
Console.Write("{0,10}, ", "Mem Nx");
Console.Write("{0,11}, ", "%age Comp");
Console.Write("{0,10}, ", "Times Comp");
Console.WriteLine("{0}", "Class Name");
}
Console.WriteLine();
Console.ResetColor();
foreach (object graph in list)
{
CompareMemoryRequirements(graph);
}
Console.WriteLine();
// Run Performance Benchmarks
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Performance Comparison");
Console.WriteLine("-----------------------------------------------------------");
if (mTabularStats)
{
Console.Write("{0,10}, ", "Time .NET");
Console.Write("{0,10}, ", "Time Nx");
Console.Write("{0,11}, ", "%age Fast");
Console.Write("{0,10}, ", "Times Fast");
Console.WriteLine("{0}", "Class Name");
}
Console.WriteLine();
Console.ResetColor();
foreach (object graph in list)
{
ComparePerformance(graph);
}
Console.WriteLine();
}
/// <summary>
/// Perform time and space comparisons.
/// </summary>
/// <param name="graph"></param>
static public void ComparePerformance(object graph)
{
if (!mTabularStats)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("-------------------------------------");
Console.WriteLine();
Console.WriteLine("Benchmarking type -- {0}", graph.GetType().FullName);
Console.WriteLine();
Console.ResetColor();
}
nstats.Measure(kIterations, kRunCount,
delegate
{
byte[] arr = NativeSerializationHelper.ToByteBuffer(graph);
NativeSerializationHelper.FromByteBuffer(arr);
}
);
cstats.Measure(kIterations, kRunCount,
delegate
{
NxBinaryFormatter formatter = new NxBinaryFormatter();
byte[] arr = formatter.ToByteArray(graph);
formatter = new NxBinaryFormatter();
formatter.FromByteArray(arr);
}
);
if (!mTabularStats)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("Time Native serialization = {0,6}", nstats.Total);
Console.WriteLine("Time NxSerialization = {0,6}", 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("NxSerialization statistics...");
Profiler.PrintExtended(cstats);
Console.WriteLine();
}
else
{
Console.Write("{0,10}, ", nstats.Total);
Console.Write("{0,10}, ", cstats.Total);
Console.Write("{0,10:F2}%, ", 100 - (float)cstats.Total / (float)nstats.Total * 100);
Console.Write("{0,10:F2}, ", (float)nstats.Total / (float)cstats.Total);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("{0}", graph.GetType().FullName);
}
Console.ResetColor();
}
/// <summary>
/// Compares the sizes of resulting streams.
/// </summary>
/// <param name="graph"></param>
static public void CompareMemoryRequirements(object graph)
{
NxBinaryFormatter formatter = new NxBinaryFormatter();
byte[] arr = NativeSerializationHelper.ToByteBuffer(graph);
byte[] arr2 = formatter.ToByteArray(graph);
if (!mTabularStats)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Stream size Native serialization = {0,6}", arr.Length);
Console.WriteLine("Stream size NxSerialization = {0,6}", 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();
}
else
{
Console.Write("{0,10}, ", arr.Length);
Console.Write("{0,10}, ", arr2.Length);
Console.Write("{0,10:F2}%, ", 100 - (float)arr2.Length / (float)arr.Length * 100);
Console.Write("{0,10:F2}, ", (float)arr.Length / (float)arr2.Length);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("{0}", graph.GetType().FullName);
}
Console.ResetColor();
}
/// <summary>
/// Performs a deep cloning operation by serializing and then deserializing the object.
/// </summary>
/// <param name="graph"></param>
/// <returns></returns>
static public object DeepClone(object graph)
{
NxBinaryFormatter formatter = new NxBinaryFormatter();
byte[] arr = formatter.ToByteArray(graph);
formatter = new NxBinaryFormatter();
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();
}
}
}
}