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());
}
}
}
我使用IPY 2.0和IPY 2.6在C#3.5中尝试上述操作。我发现IPY 2.6要慢一个数量级。这很可能是程序员错误。任何帮助,将不胜感激。
答案 0 :(得分:2)
在IronPython 2.6中,DLR已更新为使用IDynamicMetaObjectProvider作为范围对象的支持,而不是现在已弃用的IAttributesCollection接口。这使得语言可以通过调用站点缓存的方式实现全局查找。例如,您可以想象一个具有IDMOP的Web浏览器具有“文档”属性,因此语言可以快速查找常用值。
因此,虽然所有的gets / sets都要通过ObjectOperations来获取绑定器,获取或建立一个调用站点,然后通过调用站点调用。这比以前用于进行字典查找的接口调用要慢。我们可以为常见情况添加一些快速路径,以避免调用站点创建开销。
从长远来看,您将能够使用C#动态来获取/设置范围内的值,从而为您提供最佳性能。
答案 1 :(得分:0)
你在循环中做了三件事:
目前,您无法分辨哪些内容在性能方面发生了变化 - 可能全部都是如此。我建议你改变你的代码来测试它。
另外,你在.NET 4.0中尝试过2.6吗?我很想知道内置DLR的差异。完全没有任何区别,但是......
答案 2 :(得分:0)
针对上述问题的解决方法:
var scopeProvider = new Microsoft.Scripting.ScopeStorage();
scopeProvider.SetValue("B", true, 2);
var scope = engine.CreateScope(scopeProvider);
这消除了以前代码的性能开销。