C#中的深度克隆每次调用执行时间更长

C#中的深度克隆每次调用执行时间更长,c#,.net,data-structures,cloning,C#,.net,Data Structures,Cloning,我正在尝试深度克隆100个多属性对象的列表,我正在使用下面的代码执行深度克隆。列表创建和列表克隆是在一个循环中进行的,因此每次循环中列表都会更改其内容,但保持固定在100个对象 问题是每次循环中,克隆列表所花费的时间似乎都比上次执行列表所花费的时间要长 public static Main () { List<Chromosome<Gene>> population = Population.randomHalfAndHalf(rand, data, 100, opse

我正在尝试深度克隆100个多属性对象的列表,我正在使用下面的代码执行深度克隆。列表创建和列表克隆是在一个循环中进行的,因此每次循环中列表都会更改其内容,但保持固定在100个对象

问题是每次循环中,克隆列表所花费的时间似乎都比上次执行列表所花费的时间要长

public static Main ()
{

List<Chromosome<Gene>> population = Population.randomHalfAndHalf(rand, data, 100, opset);

        for (int i = 0; i < numOfGenerations; i++)
        {
                   offSpring = epoch.runEpoch(rand, population, SelectionMethod.Tournament, opset);
                    clone = DeepClone<List<Chromosome<Gene>>>(population);
                    clone.AddRange(offSpring);
                    population = fixPopulation(rand, clone, SelectionMethod.Tournament, 100);
        }

//....REST OF CODE....

}


public static T DeepClone<T>(T obj)
    {
        object result = null;

        using (var ms = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(ms, obj);
            ms.Position = 0;

            result = (T)formatter.Deserialize(ms);
            ms.Close();
        }
        return (T)result;
    }
publicstaticmain()
{
列表总体=总体。随机一半和一半(兰德,数据,100,操作集);
for(int i=0;i
你们中的一些人可能会想,如果我能写下原始人口,为什么我还要克隆这个对象。这是一个有效的观点,也是我已经探讨过的一点,但是当我这样做的时候,循环在我第一次运行它的时候完美地执行了大约8次迭代,然后它空闲,什么也不做,所以我停止了它。下一次我执行它时,它会进行9次迭代,每次循环都会停止、理想、不做任何事情等等。如果有人对为什么会发生这种情况有任何想法,也请分享,因为我真的不明白为什么会发生这种情况

但我的主要问题是,每次在上述循环中克隆对象所需的时间要长得多,先是几秒钟,然后最终达到5分钟,以此类推

有人知道为什么会这样吗

编辑我在应用程序运行时对其进行了分析。超过90%的工作是由BinaryFormatter完成的。反序列化(memoryStream)和修复填充—它不做任何会导致此问题的过于复杂的事情

private static List<Chromosome<Gene>> fixPopulation(Random rand, List<Chromosome<Gene>> oldPopulation, SelectionMethod selectionMethod, int populationSize)
    {
        if (selectionMethod == SelectionMethod.Tournament)
        {
            oldPopulation.Sort();
        }
        else
        {
            //NSGAII sorting method
        }

        oldPopulation.RemoveRange(populationSize, (oldPopulation.Count - populationSize));

        for (int i = 0, n = populationSize / 2; i < n; i++)
        {
            int c1 = rand.Next(populationSize);
            int c2 = rand.Next(populationSize);

            // swap two chromosomes
            Chromosome<Gene> temp = oldPopulation[c1];
            oldPopulation[c1] = oldPopulation[c2];
            oldPopulation[c2] = temp;
        }

        return oldPopulation;
    }
private static List fixPopulation(随机rand、List oldpropulation、SelectionMethod SelectionMethod、int populationSize)
{
如果(selectionMethod==selectionMethod.Tornament)
{
oldpropulation.Sort();
}
其他的
{
//NSGAII分类法
}
oldprotation.RemoveRange(populationSize,(oldprotation.Count-populationSize));
对于(int i=0,n=populationSize/2;i
您可以使用二进制序列化创建对象的快速克隆:

看看这个:

public Entity Copy()
        {
            System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            bFormatter.Serialize(memoryStream, this);
            memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
            IEntityForm entity= (IEntityForm)bFormatter.Deserialize(memoryStream);
            return entity;
        }

真的很容易和工作

基因
对象看起来像什么?如何在
runEpoch
中创建子代?
基因
是否碰巧包含对父基因的引用?如果是这样的话,虽然列表只包含100个项目,但每次迭代的总图表都会增加…您有调试器吗?也许写一个单元测试?@Fredrik整个对象染色体相当复杂。染色体有一个称为基因型的属性,可以设置为GeneNode,其中GeneNode是基因的二叉树@Mitch&@sehe我正在使用visual studio 2010 show,您可以访问这两个功能。如果您推荐,您可以发布修复程序吗?二叉树?你的二叉树或与之相关的数据是否在每次迭代中都变得越来越复杂?@macias发布的fix population它除了将总体大小减小到其预期大小并再次随机化之外,实际上没有什么作用。二叉树是一个不同类的外观,因此在这里不太实用我正在这样做唯一的区别是您指定了memoryStream.Seek,即使更改我的代码以反映您的代码,问题仍然存在。您是否检查了无限循环或堆栈溢出?是的,它减轻了任何堆栈溢出,但最终完成它只需要花费很长时间。