public void TestArrayCloning() { var ilCloner = new IlCloner(); var exampleArray = new[] { Enumerable.Range(0, 10) .Select(i => ExampleClass.GenerateExampleObject()) .ToArray() } .ToArray(); var cloner = IlCloner.CreateCloner(exampleArray); var cloned = cloner(exampleArray); Assert.IsFalse(Object.ReferenceEquals(exampleArray, cloned)); for (var i = 0; i < exampleArray.Length; i++) { Assert.IsFalse(Object.ReferenceEquals(exampleArray[i], cloned[i])); for (var j = 0; j < exampleArray[i].Length; j++) { Assert.IsFalse(Object.ReferenceEquals(exampleArray[i][j], cloned[i][j])); Assert.IsTrue(exampleArray[i][j].Equals(cloned[i][j])); } } }
public void TestIndexerBeingUsedForIListGeneric() { var ilCloner = new IlCloner(); var list = new TestList <int>(); for (var i = 0; i < 4; i++) { list.Add(i); } var cloner = IlCloner.CreateCloner(list); var newList = cloner(list); Assert.IsTrue(list.GetIndexerHit, "Get indexer was not accessed while cloning list"); }
public void TestNonGenericListContainingNonGenericListOfSameType() { var ilCloner = new IlCloner(); var example = new TestTwoNonGenericMembersSameType() { ListC = new TestNonGenericList() }; example.ListC.Add(new TestNonGenericList { 1, 2, 3, 4 }); var cloner = IlCloner.CreateCloner(example); var exampleCloned = cloner(example); Assert.IsFalse(Object.ReferenceEquals(example.ListC, exampleCloned.ListC)); Assert.IsFalse(Object.ReferenceEquals(example.ListC[0], exampleCloned.ListC[0])); }
public void TestNonGenericListCloning() { var ilCloner = new IlCloner(); var example = new AsList { "A", "B", "C" }; var cloner = ilCloner.CreateClonerDelegate <AsList>(); var cloned = cloner(example); Assert.IsFalse(Object.ReferenceEquals(example, cloned)); Assert.IsTrue(example.SequenceEqual(cloned)); var nonGenList = new ExampleOldSchoolList(); ((IList)nonGenList).Add(example); ((IList)nonGenList).Add(example); ((IList)nonGenList).Add(example); ((IList)nonGenList).Add(example); ((IList)nonGenList).Add(example); ((IList)nonGenList).Add(example); var clonerNonGen = IlCloner.CreateCloner(nonGenList); var clonedNonGen = clonerNonGen(nonGenList); Assert.IsFalse(Object.ReferenceEquals(nonGenList, clonedNonGen)); Assert.IsTrue(example.SequenceEqual(cloned)); for (var i = 0; i < nonGenList.Count; i++) { Assert.IsFalse(Object.ReferenceEquals(((IList)nonGenList)[i], ((IList)clonedNonGen)[i])); } }
public static Action Benchmark <T>(T obj, int countToRun = 1000000, bool cloneProps = true) where T : class, ICloneable { var message = ""; var timer = new Stopwatch(); timer.Start(); IlCloner.Default.ShouldCloneProperties = cloneProps; IlCloner.Default.UseExistingCloners = false; var example = obj; var cloneGenStart = timer.Elapsed; var cloner = IlCloner.CreateCloner <T>(); message += $"{(timer.Elapsed - cloneGenStart).TotalMilliseconds.ToString("n2")}ms to generate cloner." + Environment.NewLine; // Dry run cloner(example); example.Clone(); var actions = new[] { new { Name = "IL Generated", Action = new Action(() => cloner(example)) }, new { Name = "C# Clone() method", Action = new Action(() => example.Clone()) } }; Action iteration = () => { var deferred = new List <Action>(); var maxClonesSec = 0.0; double?minClonesSec = null; var messages = actions.ToDictionary(a => a.Name, a => new List <string>()); string fastest = null; foreach (var a in actions) { GC.Collect(); System.Threading.Thread.Sleep(1000); var startTime = timer.Elapsed; for (var i = 0; i < countToRun; i++) { a.Action(); } var totalTime = timer.Elapsed - startTime; var clonesSec = (countToRun / totalTime.TotalSeconds); maxClonesSec = Math.Max(maxClonesSec, clonesSec); if (minClonesSec.HasValue) { minClonesSec = Math.Min(minClonesSec.Value, clonesSec); } else { minClonesSec = clonesSec; } deferred.Add( () => { messages[a.Name].Add($"{clonesSec.ToString("n2")} clones per second."); if (clonesSec != maxClonesSec) { var frac = (clonesSec / maxClonesSec); messages[a.Name].Add($"{(100.0 - frac * 100.0).ToString("0.00")}% ({frac.ToString("0.00")} times) slower than best performer."); } if (clonesSec != minClonesSec.Value) { var frac = (clonesSec / minClonesSec).Value; messages[a.Name].Add($"{(frac * 100.0 - 100.0).ToString("0.00")}% ({frac.ToString("0.00")} times) faster than worst performer."); } if (clonesSec == maxClonesSec) { fastest = a.Name; } } ); } deferred.ForEach(d => d()); var nameFieldLength = actions.Max(a => a.Name.Length) + 4; message += string.Join( Environment.NewLine + Environment.NewLine, actions .Select(a => { return(string.Join( Environment.NewLine, messages[a.Name].Select((m, idx) => { if (idx == 0) { return $"{a.Name}:".PadRight(nameFieldLength) + m; } else if (idx == 1 && a.Name == fastest) { return "".PadRight(a.Name.Length, '^').PadRight(nameFieldLength) + m; } else { return "".PadRight(nameFieldLength) + m; } }) )); }) ); Console.WriteLine(message); Console.ReadLine(); message = ""; }; iteration(); return(iteration); }