简体   繁体   中英

Fastest way to compare the properties of two objects

Someone suggested using reflection for this. The method I have works great, but over 800,000 iterations, I came to the obvious conclusion (that most already came to) that reflection just doesn't cut it.

Here's part of my Helper class:

public static class Helper
{
    public static string[] ignoredProperties =
    { 
        "EntityState", 
        "EntityKey", 
        "Prop1", 
        "Prop2", 
        "Whatever", 
    };

    /// <summary>
    /// Check if properties of two objects are the same. Bypasses specified properties.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="first"></param>
    /// <param name="other"></param>
    /// <param name="ignoreProperties"></param>
    /// <returns></returns>
    public static bool PropertiesEquals<T>(this T first, T other, string[] ignoreProperties)
    {
        var propertyInfos = first.GetType().GetProperties();
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
            //Faster with custom method ? Nah...
            //if (FindElementIndex(ignoreProperties, propertyInfo.Name) < 0)

            //Probably faster if hardcoded.... Nah, not really either...
            //if (propertyInfo.Name != "EntityKey" && propertyInfo.Name != "EntityState" && propertyInfo.Name != "Group_ID" && propertyInfo.Name != "Import_status")

            if (Array.IndexOf(ignoreProperties, propertyInfo.Name) < 0)
                if (!Equals(propertyInfo.GetValue(first, null), propertyInfo.GetValue(other, null)))
                    return false;
        }
        return true;
    }

    public static int FindElementIndex(string[] input, string value)
    {
        int arraySize = input.Length - 1;
        Type valueType = value.GetType();

        for (int x = 0; x <= arraySize; x++)
        {
            if (input[x] == value)
                return x;
        }

        return -1;
    }

The problem is that those objects, depending on the type, can have up to 50 properties to check. So I can't really do a bunch of if s there.

Is there any way I could speed this up a bit?

Thanks.

You can use Reflection.Emit for creating comparing method dynamically, and then just simply running it. The code will be JITted and run fairly quickly.

There is one downside - you have to know how IL works.

Is there any way I could speed this up a bit?

Absolutely. If you're going to fetch the same properties multiple times for different objects, create a delegate for each property (see this blog post I wrote a while ago for some examples) or use a project like Hyperdescriptor .

(As of .NET 3.5, another way to create the delegate would be to use expression trees and compile them.)

You can build an Expression where you specify which properties should be compared. You can then compile it as a lambda expression and use it to compare the items with the performance of a delegate call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM