【问题标题】:Import module in IronPython 2.7.1 very slowIronPython 2.7.1 中的导入模块非常慢
【发布时间】:2012-03-08 19:33:18
【问题描述】:

(关于 StackOverflow 的第一个问题,很高兴参加 :))

我正在使用 IronPython 2.7.1 和 C# .net 4.0。

我使用 C# 来启动我的 python 脚本。 我有大约 20 个需要大量导入的个人模块。 例如:

如果我有 module1.py、module2.py、module3.py、module4.py 和 main_script.py。

main_script.py 导入模块 1 和模块 2

module1 和 module2 都导入 module3。

module1 和 module3 导入 module4

等等

模块可以有大量的代码行。

我看到的是,当我执行 main_script.py 时,导入模块大约需要 4-5 秒。

我尝试使用 pyc.py 将我的所有模块编译到一个 dll 中,然后在其上使用 ngen,但在使用 myEngine.Runtime.LoadAssembly() 添加此 dll 时我没有发现任何差异。

然后我想使用 py_compile.py 来获取 pyc 文件,但似乎无法正常工作,因为 IronPython.Modules.MarshalWriter 类不支持 IronPython.Runtime.FunctionCode 类型(函数 WriteObject(object o)。(尝试编译时出现“不可编组对象”异常)。

我对 Python 和 IronPython 都不是很熟悉,也许我没有理解该语言的所有细微之处(实际上我是这么认为的)。我正在网上寻找解决方案,但似乎我现在陷入困境。

有什么提高导入性能的想法吗?

【问题讨论】:

    标签: import module ironpython


    【解决方案1】:

    对于 IronPython 2.7.1 来说,导入需要 4-5 秒,尤其是对于大型模块,这并不意外。我会用 pyc.py 来改进它,但我也认为它不像以前那么有用了——IronPython 的导入速度比以前快了很多,所以 pyc.py 没那么有用了。

    问题是,IronPython 在导入模块时比 Python 所做的要多得多[1]。 Python 必须解析它并生成它然后执行的字节码。 IronPython 必须生成 DLR 树,然后将其转换为解释器指令 - 如果超出编译限制,还可能会转换为 IL,这意味着运行 .NET JIT 以生成机器代码。

    如果脚本只需要几秒钟的时间运行,所有这些工作都将被浪费; IronPython 更适合长时间运行的进程。然而,简短的 Python 脚本非常普遍,IronPython 对这类脚本极为不利。

    我们有两种方法可以解决这个问题,您提到了其中一种。正在开展工作以支持标准 .pyc 文件,其解释器针对启动时间而非吞吐量进行了优化 - 短脚本将受益,但长时间运行的代码将受到影响。其次,将 IronPython 移植到移动平台需要禁用动态代码生成,因此使 DLR 解释器快速变得非常重要;这项工作也将使未编译的代码更快地启动。

    我们无法克服的一件事是 .NET 进程的启动时间通常比普通 C 进程要长。这种开销可以减少,但它需要一些相当深入的优化,可能暂时不会完成。

    [1] Python 的导入过程是如此之快,以至于查找文件的 stat 调用远远大于解析和编译它的时间。

    【讨论】:

    • 好的。谢谢你的回复,很清楚。实际上,我的脚本很短,所以有时导入模块比执行脚本需要更多时间。我的主要问题是在某些情况下我要运行数百个脚本,并且每次都必须执行导入过程。但无论如何,非常感谢您的回复。
    • 我假设您将 IPy 嵌入到 C# 应用程序中,这取决于您如何表达您的问题。您是否尝试过将导入到您挂起的单个作用域,然后将该作用域用作可以在脚本中导入的全局模块。这可能会让你有更好的表现?或者您可以尝试重新使用脚本范围,如果您确信您的脚本不会被剩余变量污染(即确保您自己在脚本中重新初始化变量)
    • 抱歉,回复晚了,我不得不处理另一个主题。由于我们的系统,我无法为我的所有脚本创建一个将用作全局模块的范围,因为每个脚本都在另一个进程中执行,该进程在执行后被终止。我们在 Python 中存在内存管理问题(大量数据没有被垃圾,不知道为什么),我们找到的唯一解决方案是在单独的进程中执行每个脚本。
    猜你喜欢
    • 1970-01-01
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-15
    相关资源
    最近更新 更多