using System;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
public class Test
{
[Serializable]
public class DataItem
{
public Int32 Property1 { get; set; }
public String Property2 { get; set; }
public Int32 Property3 { get; set; }
public DataItem Parent;
public List<DataItem> Children;
}
public static void Main()
{
DataItem root = CreateTestData();
DataItem testItems1 = Clone(root);
//DataItem testItems2 = CopyProperties<DataItem, DataItem>(root);
Measure("Serialize",
delegate
{
DataItem items2 = Clone(root);
});
//Measure("Reflection",
// delegate
// {
// DataItem items3 = CopyProperties<DataItem, DataItem>(root);
// });
Console.ReadLine();
}
private static int _levels = 5;
private static int _childCount = 5;
private static int _identity = 0;
private static int GetNextId()
{
return _identity++;
}
static DataItem CreateTestData()
{
DataItem root = new DataItem { Property1 = GetNextId(), Property2 = GetNextId().ToString(), Property3 = GetNextId(), Children = new List<DataItem>() };
CreateChildren(root);
return root;
}
static void CreateChildren(DataItem parent, int level = 0)
{
for (int i = 0; i < _childCount; i++)
{
DataItem child = new DataItem
{
Property1 = GetNextId(),
Property2 = GetNextId().ToString(),
Property3 = GetNextId(),
Parent = parent
};
parent.Children.Add(child);
if (level < _levels)
{
child.Children = new List<DataItem>();
CreateChildren(child, level + 1);
}
}
}
static T Clone<T>(T target)
{
using (MemoryStream stream = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, target);
stream.Position = 0;
T result = (T)formatter.Deserialize(stream);
return result;
}
}
//static void CopyProperties<S, T>(S source, T target) where T : class
//{
// Type type = typeof(T);
// PropertyInfo[] properties = source.GetType().GetProperties();
// foreach (PropertyInfo property in properties)
// {
// PropertyInfo targetProperty = type.GetProperty(property.Name);
// if (targetProperty != null)
// targetProperty.SetValue(target, property.GetValue(source, null), null);
// }
//}
//static T[] CopyProperties<S, T>(S[] source) where T : class, new()
//{
// if (source == null)
// throw new ArgumentNullException("source");
// T[] result = new T[source.Length];
// for (Int32 loop = 0; loop < source.Length; loop++)
// {
// result[loop] = new T();
// CopyProperties(source[loop], result[loop]);
// }
// return result;
//}
static void Measure(String message, Action method)
{
Int64 mem = GC.GetTotalMemory(true);
Int64 gcCount = GC.CollectionCount(0);
DateTime now = DateTime.Now;
Stopwatch stopwatch = Stopwatch.StartNew();
method();
TimeSpan elapsed = stopwatch.Elapsed;
// DONTTOUCH:
// It is intended to call GetTotalMemory with forceFullCollection: false
// before CollectionCount call.
Double tempMemDelta = Math.Max(GC.GetTotalMemory(false) - mem, 0);
Int64 gcCountDelta = GC.CollectionCount(0) - gcCount;
String elapsedString = elapsed.TotalSeconds.ToString("00.0000", CultureInfo.InvariantCulture);
String memDeltaInKb = (tempMemDelta / 1024).ToString("0.00 KB", CultureInfo.InvariantCulture);
Console.WriteLine(@"{0}:
Elapsed: {1} s, MemDelta: {2,10}, GC count: {3}
", message, elapsedString, memDeltaInKb, gcCountDelta);
}
}