fork download
  1. using System;
  2. using System.IO;
  3. using System.Reflection;
  4. using System.Diagnostics;
  5. using System.Globalization;
  6. using System.Collections.Generic;
  7. using System.Runtime.Serialization.Formatters.Binary;
  8.  
  9. public class Test
  10. {
  11. [Serializable]
  12. public class DataItem
  13. {
  14. public Int32 Property1 { get; set; }
  15. public String Property2 { get; set; }
  16. public Int32 Property3 { get; set; }
  17. }
  18. public static void Main()
  19. {
  20. DataItem[] items = CreateTestData(Int32.Parse(Console.ReadLine()));
  21.  
  22. Measure("Serialize",
  23. delegate
  24. {
  25. DataItem[] items2 = Clone(items);
  26. });
  27. Measure("Reflection",
  28. delegate
  29. {
  30. DataItem[] items3 = CopyProperties<DataItem, DataItem>(items);
  31. });
  32. }
  33. static DataItem[] CreateTestData(Int32 count)
  34. {
  35. Random rnd = new Random();
  36. DataItem[] result = new DataItem[count];
  37. for(Int32 loop = 0; loop < count; loop++)
  38. {
  39. result[loop] = new DataItem();
  40. result[loop].Property1 = rnd.Next();
  41. result[loop].Property2 = rnd.Next().ToString();
  42. result[loop].Property3 = rnd.Next();
  43. }
  44. return result;
  45. }
  46. static T Clone<T>(T target)
  47. {
  48. using(MemoryStream stream = new MemoryStream())
  49. {
  50. BinaryFormatter formatter = new BinaryFormatter();
  51. formatter.Serialize(stream, target);
  52. stream.Position = 0;
  53. T result = (T)formatter.Deserialize(stream);
  54. return result;
  55. }
  56. }
  57. static void CopyProperties<S, T>(S source, T target) where T : class
  58. {
  59. Type type = typeof(T);
  60. PropertyInfo[] properties = source.GetType().GetProperties();
  61. foreach(PropertyInfo property in properties)
  62. {
  63. PropertyInfo targetProperty = type.GetProperty(property.Name);
  64. if(targetProperty != null)
  65. targetProperty.SetValue(target, property.GetValue(source, null), null);
  66. }
  67. }
  68. static T[] CopyProperties<S, T>(S[] source) where T : class, new()
  69. {
  70. if(source == null)
  71. throw new ArgumentNullException("source");
  72.  
  73. T[] result = new T[source.Length];
  74. for(Int32 loop = 0; loop < source.Length; loop++)
  75. {
  76. result[loop] = new T();
  77. CopyProperties(source[loop], result[loop]);
  78. }
  79. return result;
  80. }
  81. static void Measure(String message, Action method)
  82. {
  83. Int64 mem = GC.GetTotalMemory(true);
  84. Int64 gcCount = GC.CollectionCount(0);
  85.  
  86. DateTime now = DateTime.Now;
  87. Stopwatch stopwatch = Stopwatch.StartNew();
  88. method();
  89. TimeSpan elapsed = stopwatch.Elapsed;
  90.  
  91. // DONTTOUCH:
  92. // It is intended to call GetTotalMemory with forceFullCollection: false
  93. // before CollectionCount call.
  94. Double tempMemDelta = Math.Max(GC.GetTotalMemory(false) - mem, 0);
  95. Int64 gcCountDelta = GC.CollectionCount(0) - gcCount;
  96.  
  97. String elapsedString = elapsed.TotalSeconds.ToString("00.0000", CultureInfo.InvariantCulture);
  98. String memDeltaInKb = (tempMemDelta / 1024).ToString("0.00 KB", CultureInfo.InvariantCulture);
  99.  
  100. Console.WriteLine(@"{0}:
  101. Elapsed: {1} s, MemDelta: {2,10}, GC count: {3}
  102. ", message, elapsedString, memDeltaInKb, gcCountDelta);
  103. }
  104. }
Success #stdin #stdout 0.15s 34416KB
stdin
100
stdout
Serialize: 
Elapsed: 00.0851 s,  MemDelta:  156.00 KB,  GC count: 1

Reflection: 
Elapsed: 00.0079 s,  MemDelta:    8.00 KB,  GC count: 0