【发布时间】:2021-07-01 15:06:06
【问题描述】:
我有数千个数据流,我需要对其进行转换并添加到列表中。转换通过类似于以下的反射发生
_myObservable.Subscribe(d => {
PropertyInfo[] props = d.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
var propValDict = props.ToDictionary(prop => prop.Name, prop => prop.GetValue(d, null));
myList.Add(propValDict);
});
// Datatype of d is determined during runtime and there are only 8 possibilities of the type
但是这种方法会降低性能,我预计反射的使用可能是原因。我正在考虑通过其他方式提高性能。
建议似乎指向表达式树的使用,创建已编译的 lambda (Func<object,Dictionary<string, object>>) 并事先将其存储在查找字典中。
//Foreach possibleType in PossibleTypes, Do below
PropertyInfo[] props = possibleType.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
var rootParam = Expression.Parameter(typeof(object), "d");
var param = Expression.Parameter(typeof(PropertyInfo), "prop");
var propertyFirst = Expression.Property(param, "Name");
var param2 = Expression.Parameter(typeof(PropertyInfo), "prop");
var callMethod = Expression.Call(param2, typeof(PropertyInfo).GetMethod(nameof(PropertyInfo.GetValue), new Type[] { typeof(object) }), rootParam);
var pro = Expression.Parameter(typeof(Array), "props");
var toDict = Expression.Invoke(pro, propertyFirst, callMethod);
var lambda = Expression.Lambda<Func<object, Dictionary<string, object>>>(toDict, rootParam);
var compiled = lambda.Compile();
我无法调用 Enumerable 类的 ToDictionary 这种方法我缺少一些东西,或者这真的会提高性能吗?
请帮忙...
【问题讨论】:
-
如果你想知道它是否可以帮助提高性能,也许在迭代道具时在 C# 中生成等效的输出作为临时的东西(它不需要很漂亮),看看它是如何执行?
-
“这真的会提高性能吗?”几乎可以肯定不是。您在运行时做了大量工作,最终得到一个与您在第一个示例中在编译时生成的委托完全相同的委托。情况更糟。
-
@Servy 取决于它们处理相同类型实例的频率。
GetType()和GetProperties()很慢。 -
如果我是对的,至少我可以避免为每个数据调用
PropertyInfo[] props = possibleType.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);,因为可能只有八个 PropertyInfo[]。但即使我将道具信息存储在字典中,我也必须根据d.GetType()检索值 -
@canton7 但他们只是在制作一个调用这些方法的表达式。所以无论哪种方式,这种缓慢仍然存在。
标签: c# .net lambda expression-trees