我只是想玩一些东西。我做了一个OR/M类型的映射器,因为我使用反射,所以性能很慢。我怎样才能加快速度,或者使用更好、更有效的方法?
我有一个带有命名参数的自定义属性,并且允许多个然后我使用反射来:
- 获取包含自定义属性装饰的属性
- 对于找到的每个属性,获取自定义属性数据
- 对于每个自定义属性数据,获取命名参数
然后检查命名参数memberinfo name,看它是否与属性的命名参数匹配,如果匹配,则获取该命名参数的值集,最后从dataReader读取该命名参数值的数据,并使用. setvalue将从读取器读取的值设置为属性。
这里是一些代码(不以任何方式完成),并希望有人能告诉我如何获得性能改进。运行它10,000次(在此之前进行初始调用JIT演习等),我得到了这些平均时间:
3.79毫秒
手动执行(即从DB到DTO的硬编码映射):0.05ms
我知道这有点像"另一个OR/M"——但它并不完全是那样,它更多的是为了我的乐趣。
private T Populate<T>(IDataReader reader) where T : class, new()
{
T val = new T();
if (reader != null && !reader.IsClosed)
{
var propsWithSQLColumnNameAttributes = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static).Where(prop => Attribute.IsDefined(prop, typeof(SQLColumnNameAttribute)) && prop.CanWrite && prop.GetSetMethod() != null);
foreach (var currentProperty in propsWithSQLColumnNameAttributes)
{
foreach (var currentAttributeForProperty in currentProperty.GetCustomAttributesData())
{
string currentAttribParamValue = null;
foreach (var currentNamedArgument in currentAttributeForProperty.NamedArguments)
{
if (String.Equals(currentNamedArgument.MemberInfo.Name, SQLColumnNameAttribute.PropertyNames.DataColumnNamePropertyName, StringComparison.OrdinalIgnoreCase))
{
currentAttribParamValue = currentNamedArgument.TypedValue.Value == null ? null : currentNamedArgument.TypedValue.Value.ToString();
if (reader.DoesFieldExist(currentAttribParamValue))
{
var dbRecordValue = reader[currentAttribParamValue] == DBNull.Value ? null : reader[currentAttribParamValue];
currentProperty.SetValue(val, dbRecordValue, null);
}
break;
}
}
}
}
}
return val;
}
不是最好的代码,但无论如何,perf是这里的问题,想知道如何改进它,要么通过使用不同的反射方法,要么可能使用的排序和算法类型是不正确的
非常感谢-我希望这个问题是有意义的
看看这个页面http://www.codeproject.com/Articles/503527/Reflection-optimization-techniques,看看它是否对你有帮助。它讨论了许多场景下的反射优化,一旦你想学习,这可能是一个很好的资源。