2012-02-17 44 views
1

(StackOverflow上的第一個問題,很高興在那裏:))IronPython 2.7.1中的導入模塊非常慢

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

我使用C#啓動我的python腳本。 我有大約20個導入大量時間的個人模塊。 E.g:

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

main_script.py進口模塊1和模塊2

兩個模塊1和模塊2輸入單詞數。

模塊1和單詞數進口版Module

模塊可以具有大量的行代碼。

我看到的是當我執行main_script.py時,只需要4-5秒就可以導入模塊。

我試圖用pyc.py編譯dll中的所有模塊,然後使用ngen,但使用myEngine.Runtime.LoadAssembly()添加此dll時,我看不出有什麼區別。

然後,我想使用py_compile.py來獲取pyc文件,但似乎不工作,因爲IronPython.Modules.MarshalWriter類(函數WriteObject(object o))不支持IronPython.Runtime.FunctionCode類型。 (我在編譯時遇到了「unmarshallable object」異常)

我對Python和IronPython都不是很熟悉,也許我沒有理解該語言的所有細節(實際上我是這麼認爲的)。搜索網絡的解決方案,但似乎我現在卡住了。

任何想法,以提高進口性能?

回答

2

對於IronPython 2.7.1來說,花費4-5秒來完成導入操作,特別是對於大型模塊來說,這並非意料之外。我會用pyc.py來改進它,但我也認爲它不如以前那麼有用 - IronPython的導入速度比以前快很多,所以pyc.py的用處不大。

事情是,IronPython比Python導入模塊時做的要多很多[1]。 Python必須解析它併產生字節碼,然後執行它。 IronPython必須生成DLR樹,然後將其轉換爲解釋器指令 - 如果它們超出編譯限制(也就是運行.NET JIT生成機器碼),可能還需要IL。

如果腳本只需要幾秒鐘運行,那麼所有這些工作都會浪費; IronPython適用於長時間運行的進程。但是,短Python腳本非常常見,IronPython對於這類腳本來說極其糟糕。

我們正在努力解決這個問題,有兩種方法可以解決您的問題。正在開展工作以支持標準的.pyc文件,並且具有針對啓動時間而不是吞吐量優化的解釋器 - 短腳本將受益,但長時間運行的代碼將受到影響。其次,將IronPython移植到移動平臺上需要禁用動態代碼生成,因此快速構建DLR解釋器將非常重要;這項工作也會使未編譯的代碼更快啓動。

我們無法克服的一件事情是.NET進程通常比普通C進程啓動需要更長的時間。這種開銷可以減少,但它需要一些相當深的優化,可能暫時不會完成。

[1] Python的導入過程非常快,以至於stat調用找到文件的時間要比解析&時要大得多。

+0

好的。謝謝你的迴應,這很清楚。實際上,我的腳本非常短,所以有時需要更多時間導入模塊,而不是執行腳本。 我的主要問題是,我在某些情況下需要運行數百個腳本,並且每次都必須執行導入過程。 但無論如何,非常感謝您的回覆。 – GradlonGwen 2012-02-20 08:10:53

+0

我假設你將IPy嵌入到C#應用程序中,這取決於你如何解釋你的問題。你是否試圖將你的導入導入到一個單一的作用域中,然後將這個作用域作爲一個Global模塊使用,你可以在腳本中導入這個模塊。這可能會讓你獲得更好的表現?或者你可以嘗試重新使用一個腳本範圍,如果你確信你的腳本不會被剩下的變量所污染(例如確保你自己在你的腳本中重新初始化變量) – Vassi 2012-03-02 18:24:28

+0

對不起,遲到了,我有在另一個主題上工作。 由於我們的系統,我無法創建一個作爲我所有腳本的全局模塊的範圍,因爲每個腳本都在另一個執行後死亡的進程中執行。 我們在Python的內存管理方面存在問題(大量數據不是垃圾數據,不知道爲什麼),我們發現的獨特解決方案是在分離過程中執行每個腳本。 – GradlonGwen 2012-03-28 12:20:04