У меня есть следующий метод, который отображает исходный объект на дублирующий объект назначения. Однако только определенные свойства, помеченные определенным атрибутом, должны отображаться на новый объект.Может ли мое пользовательское сопоставление использовать отражение быстрее?
Мой картографа в настоящее время выглядит следующим образом:
public static class BaseObjectExtensions
{
private static readonly Dictionary<string, Attribute[]> AttributeCache = new Dictionary<string, Attribute[]>();
private static readonly Dictionary<string, PropertyInfo[]> PropertyCache = new Dictionary<string, PropertyInfo[]>();
public static void Map(this IBaseObject destination, IBaseObject source)
{
if (source == null)
{
return;
}
var t = source.GetType();
PropertyInfo[] properties;
lock (PropertyCache)
{
if (!PropertyCache.TryGetValue(t.FullName, out properties))
{
properties = t.GetProperties();
PropertyCache.Add(t.FullName, properties);
}
}
lock (AttributeCache)
{
foreach (PropertyInfo prop in properties)
{
Attribute[] attrs;
string k = t.FullName + prop;
if (!AttributeCache.TryGetValue(k, out attrs))
{
attrs = Attribute.GetCustomAttributes(prop);
AttributeCache.Add(k, attrs);
}
if (attrs.OfType<DatabaseMap>().Any())
{
prop.SetValue(destination, prop.GetValue(source));
}
}
}
}
}
Эта карта может использоваться либо на один элемент или набор элементов. Я заметил узкое место в производительности, поэтому после многих исследований я добавил в два кэша. Времена являются для больших коллекций предметов:
- Без кэша отражения: 26.6 секунд
- с кэшем отражения (ConcurrentDictionary): 31 секунд
- с кэшем отражения (замок): 4 секунды
Ускорение драматично, но я думаю, что все еще может быть лучше. После многого чтения я нашел такие вещи, как FastInvoke и another FastInvoke, но, похоже, не применил их к тому, что я пытаюсь выполнить.
Есть ли что-нибудь еще, что я могу сделать, чтобы ускорить это?
Святое дерьмо EmitMapper быстро! Теперь в миллисекундах. – Dylan