एक और बात: आप प्रतिबिंब का उपयोग कर सकते हैं। यदि आप इसे ठीक से कैश करते हैं, तो यह 1,000,000 वस्तुओं को 5.6 सेकंड में (दुख की बात है, आंतरिक वस्तुओं के साथ 16.4 सेकंड) क्लोन करेगा।
[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;
}
मैंने इसे एक सरल तरीके से मापा, वॉचर क्लास का उपयोग करके।
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;
परिणाम: भीतर की वस्तु के साथ व्यक्तित्व - 16.4, व्यक्तिवाद = अशक्त - 5.6
CopyFactory सिर्फ मेरा परीक्षण वर्ग है जहाँ मेरे पास अभिव्यक्ति के उपयोग सहित दर्जनों परीक्षण हैं। आप इसे विस्तार में या जो भी हो, दूसरे रूप में लागू कर सकते हैं। कैशिंग के बारे में मत भूलना।
मैंने अभी तक क्रमिक परीक्षण नहीं किया है, लेकिन मुझे एक लाख कक्षाओं के साथ सुधार में संदेह है। मैं कुछ तेजी से प्रोटोफ्यू / न्यूटन की कोशिश करूँगा।
पुनश्च: सादगी पढ़ने के लिए, मैंने केवल ऑटो-प्रॉपर्टी का इस्तेमाल किया। मैं FieldInfo के साथ अपडेट कर सकता हूं, या आपको इसे आसानी से लागू करना चाहिए।
मैंने हाल ही में बॉक्स से बाहर डीपक्लोन फ़ंक्शन के साथ प्रोटोकॉल बफ़र्स धारावाहिक का परीक्षण किया । यह एक लाख सरल वस्तुओं पर 4.2 सेकंड के साथ जीतता है, लेकिन जब आंतरिक वस्तुओं की बात आती है, तो यह परिणाम 7.4 सेकंड के साथ जीतता है।
Serializer.DeepClone(personList);
सारांश: यदि आपके पास कक्षाओं तक पहुंच नहीं है, तो यह मदद करेगा। अन्यथा यह वस्तुओं की गिनती पर निर्भर करता है। मुझे लगता है कि आप 10,000 वस्तुओं तक प्रतिबिंब का उपयोग कर सकते हैं (शायद थोड़ा कम), लेकिन इससे अधिक के लिए प्रोटोकॉल बफ़र्स धारावाहिक बेहतर प्रदर्शन करेंगे।