我正在尝试深度克隆 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;
}
你们中的一些人可能会想,如果我可以覆盖原始人口,我为什么还要克隆这个对象。这是一个有效的观点,我已经探索过了,但是当我这样做时会发生什么,即循环在我第一次运行它时完美地执行了大约 8 次迭代,然后它空闲并且什么也不做,所以我停止了它。下次我执行它时,它会在循环中进行 9 次迭代并停止、理想、什么都不做等等。如果有人对为什么会发生这种情况有任何想法,也请分享,因为我真的不明白为什么会发生这种情况。
但我的主要问题是,每次在上述循环周围克隆对象的时间都会明显延长几秒钟,然后最终长达 5 分钟等。
任何机构对为什么会发生这种情况有任何想法?
编辑我在应用程序运行时对应用程序进行了概要分析,超过 90% 的大部分工作是由 BinaryFormatter.Deserialize(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;
}