2016-01-22 55 views
0

鹹菜/蒔蘿/ cpickle可以用來醃製進口模塊,以提高進口速度?例如,Shapely模塊在我的系統上需要5秒鐘才能找到並加載所有需要的依賴關係,我真的很想避免這種依賴關係。Python的pickle/cpickle/dill可以加速導入嗎?

我可以醃一次我的進口,然後重新使用該酸菜,而不是每次都必須緩慢進口嗎?

+1

酸洗會如何讓您認爲它比模塊加載的標準方式更快? – dimo414

+0

如果它全部在一個文件中,那麼它不必搜索大型sys.path來尋找模塊。 – Brian

+1

搜索「sys,path」不太可能是顯着緩慢的根源。 – BrenBarn

回答

1

號第一和formost你不能泡菜模塊,你會得到一個錯誤:

>>> import pickle, re 
>>> pickle.dump(re, open('/tmp/re.p', 'wb')) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
_pickle.PicklingError: Can't pickle <class 'module'>: attribute lookup module on builtins failed 

更多概念,即使你可以序列化模塊,則只能將增加的工作量Python必須這樣做。

通常情況下,當你說import module,Python有到:

  1. 查找模塊(通常是文件系統上的文件)
  2. 分析源代碼到內存中的字節代碼的位置(和如果可能的話商店解析字節代碼作爲.pyc file),或加載到.pyc直接存儲器(如果存在)
  3. 執行是應該運行的任何代碼當模塊首次加載

如果您以某種方式醃製某個模塊,那麼您將基本上用您自己的半熟解決方案替換第2步。

  1. 找到泡菜(通常是文件系統上的文件)
  2. Unpickle它的位置返回到一個Python模塊
  3. 執行是應該運行任何代碼,當模塊首次加載

我們可以放心地認爲取消打開會比Python的內置字節碼格式慢,因爲如果不是Python,將會在封面下使用酸洗。

更重要的是,解析Python文件不是(非常)昂貴的,並且幾乎不需要任何時間。任何真正的放緩都會發生在第3步,我們沒有改變這一點。您可能會問,是否有辦法通過酸洗來跳過第三步,但在一般情況下不可以,這是不可能的,因爲無法保證模塊不會對環境的其他部分進行更改。

現在你可能對Shapely模塊有特別的瞭解,特別是可以讓你說「當導入可以安全地在運行之間緩存時,Shapely所做的所有工作」。在這種情況下,正確的做法是將contribute這樣的緩存行爲提供給庫並緩存數據正在加載,而不是代碼 Python正在導入。

0

雖然dill可以序列化一個模塊,你可以從它如何序列化一個模塊,看看它不會節省工作import。當dill序列化一個模塊時,它會調用一個函數,然後導入該模塊。所以,正如@ dimo414所述,答案是否定的。

>>> import dill 
>>> import re 
>>> _re = dill.dumps(re) 
>>> re_ = dill.loads(_re) 
>>> re_ 
<module 're' from '/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.pyc'> 
>>> _re 
'\x80\x02cdill.dill\n_import_module\nq\x00U\x02req\x01\x85q\x02Rq\x03.' 
>>> 
0

導入延遲很可能是由於加載了GEOS庫的相關共享對象。

優化這可能可以完成,但這將是非常困難的。一種方法是構建一個靜態編譯的定製python解釋器,其中包含所有的DLL和擴展模塊。但是,堅持這將是一個主要的PITA(相信我 - 我爲它工作)。

另一種選擇是將您的應用程序轉換爲服務,因此只會導致一次啓動解釋器的運行時成本。

這取決於你的實際問題,如果這是合適的。