Một điều nữa: bạn có thể sử dụng sự phản chiếu. Nếu bạn sẽ lưu trữ bộ đệm này đúng cách, thì nó sẽ sao chép 1.000.000 đối tượng trong 5,6 giây (đáng buồn là 16,4 giây với các đối tượng bên trong).
[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;
}
Tôi đã đo nó một cách đơn giản, bằng cách sử dụng lớp Watcher.
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;
KẾT QUẢ: Với đối tượng bên trong PersonInstance - 16.4, PersonInstance = null - 5.6
CopyFactory chỉ là lớp kiểm tra của tôi, nơi tôi có hàng tá bài kiểm tra bao gồm cả việc sử dụng biểu thức. Bạn có thể thực hiện điều này trong một hình thức khác trong một phần mở rộng hoặc bất cứ điều gì. Đừng quên bộ nhớ đệm.
Tôi chưa thử nghiệm tuần tự hóa, nhưng tôi nghi ngờ về sự cải tiến với một triệu lớp. Tôi sẽ thử một cái gì đó nhanh protobuf / newton.
PS: vì mục đích đọc đơn giản, tôi chỉ sử dụng tính năng tự động ở đây. Tôi có thể cập nhật với FieldInfo hoặc bạn có thể dễ dàng thực hiện việc này bằng cách riêng của mình.
Gần đây tôi đã thử nghiệm trình tuần tự hóa Bộ đệm giao thức với chức năng DeepClone. Nó chiến thắng với 4.2 giây trên một triệu vật thể đơn giản, nhưng khi nói đến vật thể bên trong, nó chiến thắng với kết quả là 7,4 giây.
Serializer.DeepClone(personList);
TÓM TẮT: Nếu bạn không có quyền truy cập vào các lớp, thì điều này sẽ giúp ích. Nếu không, nó phụ thuộc vào số lượng của các đối tượng. Tôi nghĩ rằng bạn có thể sử dụng sự phản chiếu lên tới 10.000 đối tượng (có thể ít hơn một chút), nhưng với nhiều hơn thế, bộ nối tiếp Bộ đệm Giao thức sẽ hoạt động tốt hơn.