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 static void Main() { DataItem[] items = CreateTestData(Int32.Parse(Console.ReadLine())); Measure("Serialize", delegate { DataItem[] items2 = Clone(items); }); Measure("Reflection", delegate { DataItem[] items3 = CopyProperties(items); }); } static DataItem[] CreateTestData(Int32 count) { Random rnd = new Random(); DataItem[] result = new DataItem[count]; for(Int32 loop = 0; loop < count; loop++) { result[loop] = new DataItem(); result[loop].Property1 = rnd.Next(); result[loop].Property2 = rnd.Next().ToString(); result[loop].Property3 = rnd.Next(); } return result; } static T Clone(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 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[] 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); } }