c#中的深度克隆需要更长的时间来执行每个调用
本文关键字:时间 执行 调用 深度 | 更新日期: 2023-09-27 17:50:37
我正在尝试深度克隆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分钟,等等。
有人知道为什么会发生这种情况吗?
EDIT我已经对应用程序进行了概要分析,而它运行的大部分工作超过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;
}
您可以使用二进制序列化来创建对象的快速克隆:
看这个:
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;
}
真的很容易和工作!