Python – IronPython 2.6 slower than 2.0

ironpythonperformance

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython;
using IronPython.Hosting;

namespace EmbeddedIP2_6
{
    class Program
    {
        static void Main(string[] args)
        {
            var engine = Python.CreateEngine();
            var ss = engine.CreateScriptSourceFromString("B", Microsoft.Scripting.SourceCodeKind.Expression);
            var cc = ss.Compile();
            var timer = System.Diagnostics.Stopwatch.StartNew();
            timer.Start();
            for (int i = 0; i < 10000; i++)
            {
                var scope = engine.CreateScope();
                scope.SetVariable("B", 2);
                var value = cc.Execute(scope);
            }
            timer.Stop();
            System.Console.WriteLine(timer.Elapsed.ToString());
        }
    }
}

I try the above in C# 3.5 using IPY 2.0 and IPY 2.6. I find IPY 2.6 to be more than an order of magnitude slower. This is most probably programmer error. Any help would be appreciated.

Best Answer

In IronPython 2.6 the DLR has been updated to use IDynamicMetaObjectProvider as the backing for scope objects instead of the now deprecated IAttributesCollection interface. This lets languages implement their global lookup in such a way that it too benefits from call site caching. For example you could imagine a web browser having an IDMOP which has a "document" property so the languages can quickly lookup that commonly used value.

As a consequence of that though all of the gets/sets go through ObjectOperations which needs to get a binder, get or make a call site, and then invoke via the call site. That's slower than what used to be an interface call to do a dictionary lookup. We can add some fast paths back in for the common case that avoid the call site creation overhead.

Long term you'll be able to use C# dynamic to get/set values in a scope which should give you the very best performance.