鹹菜/蒔蘿/ cpickle可以用來醃製進口模塊,以提高進口速度?例如,Shapely模塊在我的系統上需要5秒鐘才能找到並加載所有需要的依賴關係,我真的很想避免這種依賴關係。Python的pickle/cpickle/dill可以加速導入嗎?
我可以醃一次我的進口,然後重新使用該酸菜,而不是每次都必須緩慢進口嗎?
鹹菜/蒔蘿/ cpickle可以用來醃製進口模塊,以提高進口速度?例如,Shapely模塊在我的系統上需要5秒鐘才能找到並加載所有需要的依賴關係,我真的很想避免這種依賴關係。Python的pickle/cpickle/dill可以加速導入嗎?
我可以醃一次我的進口,然後重新使用該酸菜,而不是每次都必須緩慢進口嗎?
號第一和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有到:
.pyc
file),或加載到.pyc
直接存儲器(如果存在)如果您以某種方式醃製某個模塊,那麼您將基本上用您自己的半熟解決方案替換第2步。
我們可以放心地認爲取消打開會比Python的內置字節碼格式慢,因爲如果不是Python,將會在封面下使用酸洗。
更重要的是,解析Python文件不是(非常)昂貴的,並且幾乎不需要任何時間。任何真正的放緩都會發生在第3步,我們沒有改變這一點。您可能會問,是否有辦法通過酸洗來跳過第三步,但在一般情況下不可以,這是不可能的,因爲無法保證模塊不會對環境的其他部分進行更改。
現在你可能對Shapely模塊有特別的瞭解,特別是可以讓你說「當導入可以安全地在運行之間緩存時,Shapely所做的所有工作」。在這種情況下,正確的做法是將contribute這樣的緩存行爲提供給庫並緩存數據正在加載,而不是代碼 Python正在導入。
雖然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.'
>>>
導入延遲很可能是由於加載了GEOS庫的相關共享對象。
優化這可能可以完成,但這將是非常困難的。一種方法是構建一個靜態編譯的定製python解釋器,其中包含所有的DLL和擴展模塊。但是,堅持這將是一個主要的PITA(相信我 - 我爲它工作)。
另一種選擇是將您的應用程序轉換爲服務,因此只會導致一次啓動解釋器的運行時成本。
這取決於你的實際問題,如果這是合適的。
酸洗會如何讓您認爲它比模塊加載的標準方式更快? – dimo414
如果它全部在一個文件中,那麼它不必搜索大型sys.path來尋找模塊。 – Brian
搜索「sys,path」不太可能是顯着緩慢的根源。 – BrenBarn