Use a dynamically generated delegate to Improve the Performance of calling a dynamic assembly

Source: Internet
Author: User
Preface

In some cases, we need to dynamically generate a function, for example, the C # program for function graphics (simplified version) mentioned in an article recently published by Galaxy. Not long ago, our great old zhao also sent an article titled direct call of methods, reflection call and ...... Lambda expression call, he also recommends dynamic reflection library, but I don't know how to apply it here, because the input here is a string. I used codedom to implement it myself (in fact, I wanted to implement it before I came to the blog Park. I just learned it. net soon, it took a lot of detours to barely make it feasible. The blog Park is really a good place to learn and improve ^_^). I found that the performance has improved a lot, so I would like to share with you here.

 

Thoughts and goals

First, the general knowledge is that methodinfo. Invoke needs to search for metadata, which is very slow. However, calling a method through a delegate is similar to calling this method. Therefore, when you need to call a method repeatedly, you should not use methodinfo. invoke.

However, this method is input by the user dynamically. The solution is to compile the user input into a method in the dynamic assembly, but not directly methodinfo. invoke it, but another method in this dynamic program set, returns a delegate, points to the target method, and then methodinfo. invoke is another method written to obtain a delegate, and then we can call our dynamically generated target method repeatedly without using methodinfo. invoke is finished, and it is typesafe. How good is it with IDE smart prompt support!

In the era where lambda expressions or even anonymous methods are not available (that is, when I first came up with this idea), it is very troublesome to implement this because of the type of delegation. (Have you ever seen the error "XYZ type cannot be forcibly converted to XYZ type? XYZ = xyz)

Since the advent of LINQ, there has been a series of Delegate types in the BCl, such as func <t, tresult>, which makes it easier to implement this idea, lambda expressions can save the trouble of writing more methods.

 

What are you waiting? Programming implementation!

First, write the core dynamic assembly code and compile it.

private static Assembly getDynamicAssembly(){    string source = @"    public class DynamicClass    {        public static System.Func<double, double> GetFunc()        {            return ( double x ) =>            {                return x + x;            };        }        public static double Add( double x )        {            return x + x;        }    }";    var providerOptions = new Dictionary<string, string> { { "CompilerVersion", "v3.5" } };    var cp = new CSharpCodeProvider(providerOptions);    CompilerParameters cps = new CompilerParameters();    cps.GenerateExecutable = false;    cps.GenerateInMemory = true;    cps.IncludeDebugInformation = false;    cps.CompilerOptions += "/optimize /reference:System.Core.dll";    return cp.CompileAssemblyFromSource(cps, source).CompiledAssembly;}

Note that Private Static is because I have not encapsulated it, but I wrote a consoleapp to prove my idea. OK. The star method in source is getfunc (), which returns a func <double, double> delegate. The delegate pointing method is constructed by a Lambda expression, the content of this Lambda expression is what we need to dynamically generate. In addition, 2.0 is used by default when csharpcodeprovider is used, so you need to configure it. For details, refer to the msdn library. Here the hard code is entered directly. In actual application, dynamic compilation may fail, which is ignored here. The add method is to wait for the comparison method of methodinfo. invoke.

Next, compile a method to test the effect, which is very simple:

private static Stopwatch measureDynamicDelegate( Assembly asm, int length ){    var func = asm.GetType("DynamicClass").GetMethod("GetFunc").Invoke(null, null) as Func<double, double>;    var sw = Stopwatch.StartNew();    for ( int i = 0; i < length; i++ )    {        func(1d);    }    sw.Stop();    return sw;}

As you can see, it is easy to use. You only need to write func (1D), and The intelliisense support of IDE is as follows:

Then there are other tests. This will not be posted here, and the code will be provided for download.

 

Test Results

I tested it in debug and release modes, and found that the difference is not big. The call was slower for the first time and the call was faster in the future. The figure on the left shows the debug mode, and the figure on the right shows the release mode. The cycle is 65536 times. (Click to enlarge)

 

Download the test code.

 

Last

This seems faster than the data provided by Lao Zhao, but I believe the principle is the same. How can I use Zhao's fast reflection LIBRARY AND THE DYNAMIC REFLECTION library he recommends in this scenario? Thank you for your advice.

[Edit]

After sleep, I think Lao Zhao's reply is correct. The application scenarios are different. What about DYNAMIC REFLECTION library? You are welcome to continue the discussion!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.