GetCustomAttributes sure is slow

N

not_a_commie

I've got some custom serialization code that relies heavily on
Type.GetCustomAttributes, FieldInfo.GetCustomAttributes, and
PropertyInfo.GetCustomAttributes. They are all incredibly slow. Those
three account for 90% of the time in my code.

Would it be wise to cache them in a dictionary? I doubt FieldInfo and
PropertyInfo have well-implemented hash codes. And is the Property/
FieldInfo returned not dependent upon the owning instance?

Is there anything else I could do to speed those calls up? Here is
some sample code below. I really need this method to run faster.

public static void CopyContractData(this object destination, object
source)
{
var sourceProperties =
source.GetType().GetProperties(BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var destinationProperties =
destination.GetType().GetProperties(BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var property in sourceProperties)
{
var attrib = property.GetCustomAttribute<DataMemberAttribute>();
if(attrib == null) continue;
var name = property.Name;
var dest = destinationProperties.FindFirst(info =>
name.Equals(info.Name));
if (dest != null && dest.CanWrite)
{
// TODO: handle index properties
dest.SetValue(destination, property.GetValue(source, null), null);
}
else
_logger.InfoFormat("Unable to locate a matching property named
{0}", property.Name);
}

var sourceFields =
source.GetType().GetFields(BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var destinationFields =
destination.GetType().GetFields(BindingFlags.FlattenHierarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var field in sourceFields)
{
var attrib = field.GetCustomAttribute<DataMemberAttribute>();
if (attrib == null) continue;
var name = field.Name;
var dest = destinationFields.FindFirst(info =>
name.Equals(info.Name));
if (dest != null && !dest.IsInitOnly)
dest.SetValue(destination, field.GetValue(source));
else
_logger.InfoFormat("Unable to locate a matching field named {0}",
field.Name);
}
}

static public T GetCustomAttribute<T>(this PropertyInfo t, bool
inherit)
{
// TODO: put some code in here to make sure the AllowMultiple is
false
var objs = t.GetCustomAttributes(typeof(T), inherit); // all the time
is spent right here
if (objs.Length > 0)
return (T)objs[0];
return default(T);
}

static public T[] GetCustomAttributes<T>(this FieldInfo t)
{
return t.GetCustomAttributes<T>(false);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top