Example #1
0
        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]));
                }
            }
        }
Example #2
0
        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");
        }
Example #3
0
        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]));
        }
Example #4
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]));
            }
        }
Example #5
0
        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);
        }