C# Reflection: Fastest Way to Update a Property Value?

前端 未结 3 1514
醉梦人生
醉梦人生 2020-12-08 17:11

Is this the fastest way to update a property using reflection? Assume the property is always an int:

PropertyInfo counterPropertyInfo = GetProperty();
int va         


        
3条回答
  •  无人及你
    2020-12-08 17:13

    You should look at FastMember (nuget, source code], it's really fast comparing to reflection.

    I've tested these 3 implementations:

    • PropertyInfo.SetValue
    • PropertyInfo.SetMethod
    • FastMember

    The benchmark needs a benchmark function:

    static long Benchmark(Action action, int iterationCount, bool print = true)
    {
        GC.Collect();
        var sw = new Stopwatch();
        action(); // Execute once before
    
        sw.Start();
        for (var i = 0; i <= iterationCount; i++)
        {
            action();
        }
    
        sw.Stop();
        if (print) System.Console.WriteLine("Elapsed: {0}ms", sw.ElapsedMilliseconds);
        return sw.ElapsedMilliseconds;
    }
    

    A fake class:

    public class ClassA
    {
        public string PropertyA { get; set; }
    }
    

    Some test methods:

    private static void Set(string propertyName, string value)
    {
        var obj = new ClassA();
        obj.PropertyA = value;
    }
    
    private static void FastMember(string propertyName, string value)
    {
        var obj = new ClassA();
        var type = obj.GetType();
        var accessors = TypeAccessor.Create(type);
        accessors[obj, "PropertyA"] = "PropertyValue";
    }
    
    private static void SetValue(string propertyName, string value)
    {
        var obj = new ClassA();
        var propertyInfo = obj.GetType().GetProperty(propertyName);
        propertyInfo.SetValue(obj, value);
    }
    
    private static void SetMethodInvoke(string propertyName, string value)
    {
        var obj = new ClassA();
        var propertyInfo = obj.GetType().GetProperty(propertyName);
        propertyInfo.SetMethod.Invoke(obj, new object[] { value });
    }
    

    The script itself:

    var iterationCount = 100000;
    var propertyName = "PropertyA";
    var value = "PropertyValue";
    
    Benchmark(() => Set(propertyName, value), iterationCount);
    Benchmark(() => FastMember(propertyName, value), iterationCount);
    Benchmark(() => SetValue(propertyName, value), iterationCount);
    Benchmark(() => SetMethodInvoke(propertyName, value), iterationCount);
    

    Results for 100 000 iterations:

    Default setter : 3ms

    FastMember: 36ms

    PropertyInfo.SetValue: 109ms

    PropertyInfo.SetMethod: 91ms

    Now you can choose yours !!!

提交回复
热议问题