Performance IronPython 2.6比2.0慢? 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用IronPython; 使用IronPython.Hosting; 命名空间嵌入IP2_6 { 班级计划 { 静态void Main(字符串[]参数) { 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(); 对于(int i=0;i

Performance IronPython 2.6比2.0慢? 使用系统; 使用System.Collections.Generic; 使用System.Linq; 使用系统文本; 使用IronPython; 使用IronPython.Hosting; 命名空间嵌入IP2_6 { 班级计划 { 静态void Main(字符串[]参数) { 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(); 对于(int i=0;i,performance,ironpython,Performance,Ironpython,我使用IPY 2.0和IPY 2.6在C#3.5中尝试了上述方法。我发现IPY 2.6要慢一个数量级以上。这很可能是程序员的错误。任何帮助都将不胜感激 你在循环中做了三件事: 创建范围 在范围内设置变量 执行脚本 目前,您无法判断其中哪一个在性能方面发生了变化——可能所有这些都发生了变化。我建议您更改代码以测试此功能 另外,您是否在.NET4.0中尝试过2.6?我很想听听内置DLR的区别是什么。很可能根本没有区别,但是在IronPython 2.6中,DLR已经更新为使用IDynamicMe

我使用IPY 2.0和IPY 2.6在C#3.5中尝试了上述方法。我发现IPY 2.6要慢一个数量级以上。这很可能是程序员的错误。任何帮助都将不胜感激

你在循环中做了三件事:

  • 创建范围
  • 在范围内设置变量
  • 执行脚本
目前,您无法判断其中哪一个在性能方面发生了变化——可能所有这些都发生了变化。我建议您更改代码以测试此功能


另外,您是否在.NET4.0中尝试过2.6?我很想听听内置DLR的区别是什么。很可能根本没有区别,但是在IronPython 2.6中,DLR已经更新为使用IDynamicMetaObjectProvider作为范围对象的支持,而不是现在不推荐的IAttributesCollection接口。这使得语言可以通过调用站点缓存的方式实现全局查找。例如,您可以想象一个web浏览器有一个IDMOP,它有一个“document”属性,因此语言可以快速查找常用值

因此,尽管所有的get/set都要执行objectoperation,而objectoperation需要获取绑定器、获取或创建调用站点,然后通过调用站点进行调用。这比以前进行字典查找的接口调用要慢。我们可以为常见情况添加一些快速路径,以避免呼叫站点创建开销


从长远来看,您将能够使用C#dynamic在一个范围内获取/设置值,从而获得最佳性能。

上述问题的解决方法:

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());
        }
    }
}

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

不是很重要,但是
Start
StartNew
之后是多余的。它处于执行状态。在任何情况下,我的问题都与2.6比2.0更快、更好的嵌入式应用的想法更不符。从这个意义上讲,上述案例似乎是一个“hello world”示例。是的,在DLR上运行2.6的结果会很有趣。@unknown:是的,它看起来确实像一个“hello world”示例-您是否尝试过在脚本中做得更多的东西?例如,如果2.6的启动/关闭速度变慢了,但执行引擎速度加快了,那么这可能是非常重要的,也可能是相反的情况!初步测试表明,情况可能正好相反。启动/关闭速度更快。当然,可能只是我在某个地方需要某种标志(我在ModeleOptions和CompilerOptions中尝试了所有的标志)。我的测试代码中有一个错误。事实证明,在作用域上的“SetVariable”中,它实际上较慢。对不起,谢谢你,迪诺。我还看到你把问题分配给了自己。我将在beta C#4.0中尝试这一点,看看情况是否更好。您上面的最后一句话是否取决于IPY的未来版本,或者在与beta C#4.0一起使用时,当前版本是否如此?在3.5版本中有没有办法解决这个问题?e、 实现我自己的IDynamicMetaObjectProvider。。。无论如何,感谢您的及时回复。嵌入式IPY提供了一种为应用程序提供全面脚本(以及用户自定义)的好方法。我喜欢C#和IPY的组合。如果说“与beta C#4.0一起使用时的当前版本”,你是指用于.NET 4.0 beta 2的IronPython 2.6 CTP,那么是的。如果它是为.NET2.0编译的IronPython版本,那么它将不起作用(因为IDMOP实现将不是完全相同的类型)。
var scopeProvider = new Microsoft.Scripting.ScopeStorage();
scopeProvider.SetValue("B", true, 2);
var scope = engine.CreateScope(scopeProvider);