Saturday, November 26, 2016

10x faster than Delegate.DynamicInvoke

This is a follow up to my previous blog posts, Optimizing Dynamic Method Invokes in .NET, and Dynamically Invoke Methods Quickly, with InvokeHelpers.EfficientInvoke. Basically, I have re-implemented this for Tact.NET in a way that makes it smaller, faster, and compatible with the .NET Standard.

So, how much faster is this new way of doing things? EfficientInvoker.Invoke is over 10x faster than Delegate.DynamicInvoke, and 10x faster than MethodInfo.Invoke.

Check out the source on GitHub:

Simple Explanation

Here is an example of a method and a class that we might want to invoke dynamically...

public class Tester
{
    public bool AreEqual(int a, int b)
    {
        return a == b;
    }
}

...and then here is the code that the EfficientInvoker will generate at runtime to call that method:

public static object GeneratedFunction(object target, object[] args)
{
    return (object)((Tester)target).AreEqual((int)args[0], (int)args[1]);
}

See, it's simple!

Sample Tests

public class EfficientInvokerTest
{
    public void DelegateInvoke()
    {
        var del = (Delegate) new Func<int, int, bool>((a, b) => a == b);
            
        // Standard slow way
        var result1 = (bool)del.DynamicInvoke(1, 2);
        Assert.False(result1);
 
        // New 10x faster way
        var invoker = del.GetInvoker();
        var result2 = (bool)invoker.Invoke(del, 1, 2);
        Assert.False(result2);
    }
    
    public void MethodInvoke()
    {
        var tester = new Tester();
        var type = tester.GetType();
 
        // Standard slow way
        var methodInfo = type.GetTypeInfo().GetMethod("AreEqual");
        var result1 = (bool) methodInfo.Invoke(tester, new object[] {1, 2});
        Assert.False(result1);
 
        // New 10x faster way
        var invoker = type.GetMethodInvoker("AreEqual");
        var result2 = (bool) invoker.Invoke(tester, 1, 2);
        Assert.False(result2);
    }
    
    private class Tester
    {
        public bool AreEqual(int a, int b)
        {
            return a == b;
        }
    }
}

Enjoy,
Tom

11 comments:

  1. Hi, i cannot check the source on GitHub !
    any help?

    ReplyDelete
  2. https://github.com/tdupont750/tact.net/blob/master/framework/src/Tact/Reflection/EfficientInvoker.cs

    ReplyDelete
  3. Thankyou for this! I needed something super fast with minimal garbage. This looks like it does the job.

    ReplyDelete
  4. If you are facing any challenges in arranging any place 토토사이트

    ReplyDelete
  5. I have gone through this article named ' Walk My World Learning Event'. It was a very informative article 룰렛

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Excellent Blog! I would like to thank for the efforts you have made in writing this post. I am hoping the same best work from you in the future as well. Feel free to visit my website; 일본야동

    ReplyDelete
  8. GitHub links are broken, please update :(

    ReplyDelete
  9. I am thrilled to discover this article highlighting the "Best Sainik School Coaching In Jaipur South." As a proud student of the Asian Defence Academy, I can attest to the exceptional coaching and guidance provided by this esteemed institution. Asian Defence Academy goes beyond traditional coaching by fostering a holistic learning environment that not only prepares students academically but also instills discipline and leadership qualities. The dedicated faculty and state-of-the-art facilities at the academy have been instrumental in shaping the future

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete

Real Time Web Analytics