IronPython 2.6比2.0慢?

时间:2010-01-04 20:23:56

标签: performance ironpython

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要慢一个数量级。这很可能是程序员错误。任何帮助,将不胜感激。

3 个答案:

答案 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);

这消除了以前代码的性能开销。