是否可以加快这种方法的速度?

编程入门 行业动态 更新时间:2024-10-11 09:26:28
本文介绍了是否可以加快这种方法的速度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个方法,它通过 7,753+ 个对象使用循环并获取每个对象的每个属性的值.每个对象都有 14 个属性.

I have a method that uses loops through 7,753+ objects and Gets the value of each property for each object. Each object has 14 properties.

private void InitializeData(IList objects, PropertyInfo[] props, List<DPV> dataPs, List<Dictionary<string, object>> tod) { foreach (var item in objects) { var kvp = new Dictionary<string, object>(); foreach (var p in props) { var dataPs = dataPs.FirstOrDefault(x => x.Name == p.Name); object returnData; if (dataPoint != null) { int maxLength = (dataP.MaxLength == null) ? 0 : (int) dataP.MaxLength; returnData = p.GetValue(item, null); if (!string.IsNullOrEmpty(dataP.FormatString) && !string.IsNullOrEmpty(returnData.ToString())) { returnData = FormatDataForDisplay(returnData, dataP, maxLength, "", 8); } } else { returnData = p.GetValue(item, null); } kvp.Add(p.Name, returnData); } tod.Add(kvp); } }

我相信 GetValue 是这个方法中花费大部分时间的方法,该方法花费了大约 900ms 来运行,但是 GetValue被调用 800,000+ 次大约需要 750 毫秒(总共,不是每次调用).

I believe GetValue is what takes the majority of the time in this method, The method took around 900ms to run, but GetValue which is called 800,000+ times takes around 750ms (total, not per-call).

public List<Dictionary<string, object>> GetColumnOptions<T>(List<T> list) { var tod= new List<Dictionary<string, object>>(); var objects = (IList)list[0]; Type objType = objects[0].GetType(); var props = objType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance); var dPs= GetDPs(); //Initialize aaData //I don't believe this is correct InitializeData2<T>(new List<T> { (T) objects}, props, dPs, tod); return tod; }

推荐答案

对于您的值类,您可以创建直接的 setter 和 getter lambda.性能几乎与直接访问属性一样快.

For your value class you can create direct setter and getter lambda. The performance is nearly as fast as directly accessing the properies.

从 PropertyInfo 获取 Setter

var propertyInfo = typeof(MyType).GetProperty("MyPropertValue"); var propertySetter = FastInvoke.BuildUntypedSetter<T>(propertyInfo)); var fieldInfo = typeof(MyType).GetField("MyFieldValue"); var fieldSetter = FastInvoke.BuildUntypedSetter<T>(fieldInfo));

循环使用

var myTarget = new MyType(); setter(myTarget, aNewValue)

检索快速 Setter 和 Getter 的助手

public static class FastInvoke { public static Func<T, object> BuildUntypedGetter<T>(MemberInfo memberInfo) { var targetType = memberInfo.DeclaringType; var exInstance = Expression.Parameter(targetType, "t"); var exMemberAccess = Expression.MakeMemberAccess(exInstance, memberInfo); // t.PropertyName var exConvertToObject = Expression.Convert(exMemberAccess, typeof(object)); // Convert(t.PropertyName, typeof(object)) var lambda = Expression.Lambda<Func<T, object>>(exConvertToObject, exInstance); var action = lambda.Compile(); return action; } public static Action<T, object> BuildUntypedSetter<T>(MemberInfo memberInfo) { var targetType = memberInfo.DeclaringType; var exInstance = Expression.Parameter(targetType, "t"); var exMemberAccess = Expression.MakeMemberAccess(exInstance, memberInfo); // t.PropertValue(Convert(p)) var exValue = Expression.Parameter(typeof(object), "p"); var exConvertedValue = Expression.Convert(exValue, GetUnderlyingType(memberInfo)); var exBody = Expression.Assign(exMemberAccess, exConvertedValue); var lambda = Expression.Lambda<Action<T, object>>(exBody, exInstance, exValue); var action = lambda.Compile(); return action; } private static Type GetUnderlyingType(this MemberInfo member) { switch (member.MemberType) { case MemberTypes.Event: return ((EventInfo)member).EventHandlerType; case MemberTypes.Field: return ((FieldInfo)member).FieldType; case MemberTypes.Method: return ((MethodInfo)member).ReturnType; case MemberTypes.Property: return ((PropertyInfo)member).PropertyType; default: throw new ArgumentException ( "Input MemberInfo must be if type EventInfo, FieldInfo, MethodInfo, or PropertyInfo" ); } } }

============ 添加了性能分析 ====================


============= Performance Analysis Added ===================

5 个 Mio 对象,20 个属性

  • 3.4s 直接访问属性
  • 130.0s 通过 PropertyInfo.SetValue
  • 4.0s 通过 TypedSetter(文章中显示的代码)
  • 9.8s 通过 UnTypedSetter(上面的代码)
  • 3.4s direct Property access
  • 130.0s via PropertyInfo.SetValue
  • 4.0s via TypedSetter (code shown in article)
  • 9.8s via UnTypedSetter (code above)

诀窍是为每个类生成一次 property-setter 和 -getter,然后重用它们.

The trick is to generate the property-setter and -getter once for each class an reuse them.

// Create an fill objects fast from DataReader // flurfunk.sdx-ag.de/2012/05/c-performance-bei-der-befullungmapping.html static List<T> CreateObjectFromReader<T>(IDataReader reader) where T : new() { // Prepare List<string> fieldNames = GetFieldNames(reader); List<Action<T, object>> setterList = new List<Action<T, object>>(); // Create Property-Setter and store it in an array foreach (var field in fieldNames) { var propertyInfo = typeof(T).GetProperty(field); setterList.Add(FastInvoke.BuildUntypedSetter<T>(propertyInfo)); } Action<T, object>[] setterArray = setterList.ToArray(); // generate and fill objects while (reader.Read()) { T xclass = new T(); int fieldNumber = 0; for (int i = 0; i< setterArray.Length; i++) { // call setter setterArray[i](xclass, reader.GetValue(i)); fieldNumber++; } result.Add(xclass); } }

我的原始文章(德语文本和旧代码)是 web.archive/web/20141020092917/flurfunk.sdx-ag.de/2012/05/c-性能-bei-der-befullungmapping.html

My original article (german text and older code) was web.archive/web/20141020092917/flurfunk.sdx-ag.de/2012/05/c-performance-bei-der-befullungmapping.html

更多推荐

是否可以加快这种方法的速度?

本文发布于:2023-10-26 17:32:57,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1530848.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:速度   这种方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!