Başka bir şey: yansıma kullanabilirsiniz. Bunu düzgün bir şekilde önbelleğe alırsanız, 5.000 saniyede 1.000.000 nesneyi (ne yazık ki iç nesnelerle 16.4 saniye) klonlar.
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Person
{
...
Job JobDescription
...
}
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
public class Job
{...
}
private static readonly Type stringType = typeof (string);
public static class CopyFactory
{
static readonly Dictionary<Type, PropertyInfo[]> ProperyList = new Dictionary<Type, PropertyInfo[]>();
private static readonly MethodInfo CreateCopyReflectionMethod;
static CopyFactory()
{
CreateCopyReflectionMethod = typeof(CopyFactory).GetMethod("CreateCopyReflection", BindingFlags.Static | BindingFlags.Public);
}
public static T CreateCopyReflection<T>(T source) where T : new()
{
var copyInstance = new T();
var sourceType = typeof(T);
PropertyInfo[] propList;
if (ProperyList.ContainsKey(sourceType))
propList = ProperyList[sourceType];
else
{
propList = sourceType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
ProperyList.Add(sourceType, propList);
}
foreach (var prop in propList)
{
var value = prop.GetValue(source, null);
prop.SetValue(copyInstance,
value != null && prop.PropertyType.IsClass && prop.PropertyType != stringType ? CreateCopyReflectionMethod.MakeGenericMethod(prop.PropertyType).Invoke(null, new object[] { value }) : value, null);
}
return copyInstance;
}
Watcher sınıfını kullanarak basit bir şekilde ölçtüm.
var person = new Person
{
...
};
for (var i = 0; i < 1000000; i++)
{
personList.Add(person);
}
var watcher = new Stopwatch();
watcher.Start();
var copylist = personList.Select(CopyFactory.CreateCopyReflection).ToList();
watcher.Stop();
var elapsed = watcher.Elapsed;
SONUÇ: PersonInstance - 16.4 iç nesnesi ile PersonInstance = null - 5.6
CopyFactory, ifade kullanımı da dahil olmak üzere onlarca testimin olduğu test sınıfım. Bunu başka bir biçimde bir uzantıda ya da her neyse uygulayabilirsiniz. Önbelleğe almayı unutmayın.
Serileştirmeyi henüz test etmedim, ancak bir milyon sınıfla yapılan bir iyileşmeden şüphe ediyorum. Hızlı bir şekilde protobuf / newton deneyeceğim.
PS: basitlik okumak amacıyla, ben sadece burada otomatik mülkiyet kullandım. FieldInfo ile güncelleyebilirim, ya da bunu kendi başınıza kolayca uygulamanız gerekir.
Son zamanlarda DeepClone fonksiyonu ile Protokol Tamponları serileştiricisini test ettim . Bir milyon basit nesnede 4.2 saniye kazanır, ancak iç nesneler söz konusu olduğunda, 7.4 saniye ile kazanır.
Serializer.DeepClone(personList);
Hepsini kapa Özet: Sınıflara erişiminiz yoksa, bu yardımcı olacaktır. Aksi takdirde, nesnelerin sayısına bağlıdır. Sanırım 10.000 nesneye kadar yansımayı kullanabilirsiniz (belki biraz daha az), ancak bundan daha fazlası için Protokol Tamponları serileştirici daha iyi performans gösterecektir.