lundi 21 mars 2016

Very slow Reflection (trying to write a generic wrapper)

I'm trying to write a generic method to wrap an SDK we're using. The SDK provides "AFElement" objects that represent our data object, and each data AFElement has a collection of "AFAttributes" that map to our data objects' properties.

I've created a generic method which uses reflection to check the object it's called for's properties and get them (if they exist) from the AFElement.Attributes:

private T ConvertAFElementTo<T>(AFElement element, T item) where T : class, new()
{
    PropertyInfo[] properties = item.GetType().GetProperties();
    foreach (PropertyInfo property in properties)
    {
        //Get the Attribute object that represents this property
        AFAttribute attribrute = element.Attributes[property.Name];
        if (attribrute != null)
        {
            //check if we have the same type
            if (property.PropertyType.Equals(attribrute.Type))
            {
                //set our property value to that of the attribute
                var v = attribrute.GetValue().Value;
                property.SetValue(item, v);
            }
            //check if we have an AFElement as an Attribute that will need converting to a data object
            else if (attribrute.Type.Equals(typeof(AFElement)))
            {
                AFElement attributeElement = attribrute.GetValue().Value as AFElement;
                Type attributeType = null;

                //look up it's data type from the template
                TypeConversionDictionary.TryGetValue(attributeElement.Template, out attributeType);

                if (attributeType != null)
                {
                    //set it as a .NET object
                    property.SetValue(item, ConvertAFElementTo(attributeElement, Activator.CreateInstance(attributeType)));
                }
            }
        }
    }
    return item;
}

The idea is I can throw any of my data objects T at this method and it would populate them, and it works, except it's exceptionally slow.

It takes around 10 seconds to get 63 objects, 93% of the time is in this conversion method. I've heard reflection wasn't very efficient, but is is this inefficient?

Is there any other way I could do this, or a way to speed things up? Am I being stupid even trying to do something this generic?





Aucun commentaire:

Enregistrer un commentaire