Run dynamically compiled C# code at native speed… how?

后端 未结 3 1178
野的像风
野的像风 2020-12-28 21:56

I have read several posts on SO about writing and compiling dynamic C# code. For example, this post. I understand it can be done several ways.

However, calling the c

3条回答
  •  一向
    一向 (楼主)
    2020-12-28 22:33

    Thought it was worth showing how all potential options looked and their performance characteristics. Given the following helper classes and functions:

    public void Test(Func func)
    {        
        var watch = new Stopwatch();
        watch.Start();
        for (var i = 0; i <= 1000000; i++)
        {
            var test = func();
        }
        Console.WriteLine(watch.ElapsedMilliseconds);
    }
    
    public class FooClass { public int Execute() { return 1;}}
    

    Set up and execution:

    using (Microsoft.CSharp.CSharpCodeProvider foo = 
           new Microsoft.CSharp.CSharpCodeProvider())
    {
        var res = foo.CompileAssemblyFromSource(
            new System.CodeDom.Compiler.CompilerParameters() 
            {  
                GenerateInMemory = true 
            }, 
            "public class FooClass { public int Execute() { return 1;}}"
        );
    
        var real = new FooClass();
        Test(() => real.Execute());                   // benchmark, direct call
    
        var type = res.CompiledAssembly.GetType("FooClass");
        var obj = Activator.CreateInstance(type);    
        var method = type.GetMethod("Execute");
        var input = new object[] { };                
        Test(() => (int)method.Invoke(obj, input));   // reflection invoke  
    
        dynamic dyn = Activator.CreateInstance(type);  
        Test(() => dyn.Execute());                    // dynamic object invoke
    
        var action = (Func)Delegate.CreateDelegate(typeof(Func), null, method); 
        Test(() => action());                         // delegate
    }
    

    The results are:

    8     // direct
    771   // reflection invoke
    41    // dynamic object invoke
    7     // delegate
    

    So in those cases where you can't use delegates (if you don't know enough?), you can try dynamic.

提交回复
热议问题