By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,567 Members | 1,609 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,567 IT Pros & Developers. It's quick & easy.

GetCustomAttributes sure is slow

P: n/a
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.Flatte nHierarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var destinationProperties =
destination.GetType().GetProperties(BindingFlags.F lattenHierarchy |
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.FlattenHie rarchy |
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
var destinationFields =
destination.GetType().GetFields(BindingFlags.Flatt enHierarchy |
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);
}

Jun 27 '08 #1
Share this Question
Share on Google+
1 Reply


P: n/a
On Tue, 24 Jun 2008 16:20:53 -0700, not_a_commie <no********@gmail.com>
wrote:
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?
I think a dictionary should work fine. It doesn't look like those classes
override Equals() or GetHashCode(), but as long as the instances returned
are statically associated with the type, that should be fine. It should
be easy enough for you to check that. If it turns out a new instance of
those classes is created each time you call the appropriate "Get..."
method, then you'll have to use something else for your key. But it
should not be hard to come up with a string that uniquely describes the
data. :)

As for the speed issue, yes...reflection is slow. It's a good reason to
not write code that relies on it. It is almost always the wrong approach
to solving an issue.

Pete
Jun 27 '08 #2

This discussion thread is closed

Replies have been disabled for this discussion.