Reputation: 134
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.
Upvotes: 2
Views: 326
Reputation: 134
Workaround for above problem:
var scopeProvider = new Microsoft.Scripting.ScopeStorage();
scopeProvider.SetValue("B", true, 2);
var scope = engine.CreateScope(scopeProvider);
This gets rid of the performance overhead with the previous code.
Upvotes: 0
Reputation: 6486
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.
Upvotes: 2
Reputation: 1503290
You're doing three things within the loop:
Currently you can't tell which of these has changed in performance terms - possibly all of them. I would suggest you change your code to test this.
Also, have you tried 2.6 within .NET 4.0? I'd be interested to hear what the differences are like with the built-in DLR. Quite possibly no difference at all, but...
Upvotes: 0