Archives

Archives / 2013 / October
  • Delegate performance of Roslyn Sept 2012 CTP is impressive

    I wanted to dynamically compile some delegates using Roslyn. I came across this article by Piotr Sowa. The article shows that the delegate compiled with Roslyn CTP was not very fast. Since the article was written using the Roslyn June 2012, I decided to give Sept 2012 CTP a try.

    There are significant changes in Roslyn Sept 2012 CTP in both C# syntax supported as well as API. I found Anoop Madhisidanan’s article that has an example of the new API. With that, I was able to put together a comparison. In my test, the Roslyn compiled delegate is as fast as C# (VS 2012) compiled delegate. See the source code below and give it a try.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    using Roslyn.Compilers;
    using Roslyn.Scripting.CSharp;
    using Roslyn.Scripting;
    
    namespace RoslynTest
    {
        class Program
        {
            public Func del;
    
            static void Main(string[] args)
            {
                Stopwatch stopWatch = new Stopwatch();
    
                Program p = new Program();
                p.SetupDel(); //Comment out this line and uncomment the next line to compare
                //p.SetupScript();
                stopWatch.Start();
                int result = DoWork(p.del);
                stopWatch.Stop();
                Console.WriteLine(result);
                Console.WriteLine("Time elapsed {0}", stopWatch.ElapsedMilliseconds);
                Console.Read();
            }
    
            private void SetupDel()
            {
                del = (s, i) => ++s;
            }
    
            private void SetupScript()
            {
                //Create the script engine 
                //Script engine constructor parameters go changed 
                var engine=new ScriptEngine(); 
                
                //Let us use engine's Addreference for adding the required 
                //assemblies 
                new[] 
                { 
                    typeof (Console).Assembly, 
                    typeof (Program).Assembly, 
                    typeof (IEnumerable<>).Assembly, 
                    typeof (IQueryable).Assembly 
                }.ToList().ForEach(asm => engine.AddReference(asm)); 
                
                new[] 
                { 
                    "System", 
                    "System.Linq", 
                    "System.Collections", 
                    "System.Collections.Generic" 
                }.ToList().ForEach(ns=>engine.ImportNamespace(ns)); 
                //Now, you need to create a session using engine's CreateSession method, 
                //which can be seeded with a host object 
                var session = engine.CreateSession();
    
                var submission = session.CompileSubmission>("new Func((s, i) => ++s)");
                del = submission.Execute();
                //- See more at: http://www.amazedsaint.com/2012/09/roslyn-september-ctp-2012-overview-api.html#sthash.1VutrWiW.dpuf       
            }
    
            private static int DoWork(Func del)
            {
                int result = Enumerable.Range(1, 1000000).Aggregate(del);
                return result;
            }
        }
    }
    

     

    Since Roslyn Sept 2012 CTP is already over a year old, I cannot wait to see a new version coming out.