如何高效CLONE?
public class oddsRecoder : ICloneable, IDisposable{ private bool bool_0; private string _guid = string.Empty; public IDictionary<string, IDictionary<string, IDictionary<string, string>>> dictionary = new Dictionary<string, IDictionary<string, IDictionary<string, string>>>(); private IDictionary<string, dic_PlayData> DataCollection = new Dictionary<string, dic_PlayData>(); public object Clone() { try { MemoryStream serializationStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(serializationStream, this); serializationStream.Position = 0L; Thread.GetDomain().AssemblyResolve += new ResolveEventHandler(this.m0000ca); object obj2 = formatter.Deserialize(serializationStream); Thread.GetDomain().AssemblyResolve -= new ResolveEventHandler(this.m0000ca); return obj2; } catch (Exception ex) { Console.Write(ex.Message); Log.a(ex, 1000); } return null; } public void Dispose() { this.m000075(true); GC.SuppressFinalize(this); }
static List<FieldInfo> GetSettableFields(Type t) { return t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).ToList(); } //暂时只能支持简单类的克隆,也就是类的内部只有基础类型。 static Func<object, object> CreateCloneMethod(Type type) { var fields = GetSettableFields(type); var dm = new DynamicMethod(string.Format("Clone{0}", Guid.NewGuid()), typeof(object), new[] { typeof(object) }, true); var il = dm.GetILGenerator(); il.DeclareLocal(type); il.DeclareLocal(type); il.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stloc_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Castclass, type); il.Emit(OpCodes.Stloc_0); foreach (var field in fields) { il.Emit(OpCodes.Ldloc_1); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldfld, field); il.Emit(OpCodes.Stfld, field); } il.Emit(OpCodes.Ret); return (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); }
[解决办法]
效率比较:
Func<object, object> clone = CreateCloneMethod(typeof(DT_USER));DT_USER u1 = new DT_USER() { USER_NO = 1, USER_LNAME = "001" };DT_USER u2 = null;Stopwatch sw = new Stopwatch();sw.Start();for (int i = 0; i < 100000; i++){ u2 = u1.Clone();}sw.Stop();Console.WriteLine("手写代码克隆执行10万次所用时间:" + sw.ElapsedMilliseconds + "毫秒");sw.Restart();for (int i = 0; i < 100000; i++){ u2 = clone(u1) as DT_USER;}sw.Stop();Console.WriteLine("Emit执行10万次所用时间:" + sw.ElapsedMilliseconds + "毫秒");sw.Restart();for (int i = 0; i < 100000; i++){ MemoryStream serializationStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(serializationStream, u1); serializationStream.Position = 0; u2 = formatter.Deserialize(serializationStream) as DT_USER; serializationStream.Close();}sw.Stop();Console.WriteLine("序列化方式执行10万次所用时间:" + sw.ElapsedMilliseconds + "毫秒");
[解决办法]
要是跟我一样对Emit不熟的话还是硬编码执行速度最快了。
[解决办法]