2013-03-18 44 views
6

我有一個框架,由多用戶環境下用python編寫的不同工具組成。如何加速python啓動和/或減少加載庫時的文件搜索?

我第一次登錄到系統並啓動一個命令時,需要6秒鐘來顯示幾行幫助。如果我立即再次發出相同的命令,則需要0.1s。幾分鐘後,它回到6秒。 (短期緩存證明)

系統位於GPFS上,因此磁盤吞吐量應該可以,儘管由於系統中的文件數量而導致訪問可能很低。

strace -e open python tool | wc -l 

顯示啓動該工具時正在訪問的2154個文件。

strace -e open python tool | grep ENOENT | wc -l 

顯示1945個正在查找的缺少文件。 (一個非常不好的命中/錯過率是你問我:-)

我有一個預感,涉及加載工具的過多時間是通過查詢關於所有這些文件的GPFS消耗的,並且這些緩存給下一個(無論是系統還是GPFS級別),但我不知道如何測試/證明它。 我對系統沒有root訪問權限,我只能寫入GPFS和/ tmp。

可以改進這個python quest for missing files

關於如何以簡單的方式測試這個任何想法? (在/ tmp上重新安裝所有內容並不簡單,因爲涉及的軟件包很多,virtualenv也無濟於事(我認爲),因爲它只是鏈接gpfs系統上的文件)。

一個選項當然會有一個守護進程分叉,但這遠非「簡單」並且是最後的解決方案。

感謝您的閱讀。

回答

2

如何使用imp模塊?特別是有一個功能: imp。這裏的find_module(模塊,路徑)http://docs.python.org/2.7/library/imp.html

至少這個例子(見下面)減少了open()系統調用的數量vs簡單的'import numpy,scipy':(更新:但它看起來不可能實現系統調用的顯著減少這樣......)

import imp 
import sys 


def loadm(name, path): 
    fp, pathname, description = imp.find_module(name,[path]) 
    try: 
     _module = imp.load_module(name, fp, pathname, description) 
     return _module 
    finally: 
     # Since we may exit via an exception, close fp explicitly. 
     if fp: 
      fp.close() 


numpy = loadm("numpy", "/home/username/py-virtual27/lib/python2.7/site-packages/") 
scipy = loadm("scipy", "/home/username/py-virtual27/lib/python2.7/site-packages/") 

我想你也最好先檢查一下你的PYTHONPATH是空的或小的,因爲這也可以增加加載時間。

+0

事實上,我嘗試了這一點,它看起來很有希望,儘管所有默認庫都是在啓動時運行的,我無法告訴python應該從哪個文件加載模塊,但是讓它在目錄中搜索它,導致4 open()調用和至少2次失敗。我只希望有一種告訴python不要這樣做的方法。 – estani 2013-03-18 19:03:14

2

Python 2首先查找相對於當前包的模塊。如果你的庫代碼對很多頂級模塊有很多的輸入,那麼這些模塊都是首先查找的。因此,如果包foo.bar導入os,那麼Python 第一個尋找foo/bar/os.py。這個錯誤也被Python本身緩存。

在Python 3中,默認情況下已移至絕對導入;您可以切換的Python 2.5和最多使用絕對進口每個模塊有:

from __future__ import absolute_import 

文件查找失誤的另一個原因是加載.pyc字節的緩存文件;如果由於某種原因缺少這些內容(文件系統對於當前Python進程不可寫),那麼Python將繼續在每次運行中查找這些內容。您可以用compileall module創建這些緩存:

python -m compileall /path/to/directory/with/pythoncode 

提供運行與正確的寫權限。

+0

hmmm ...我在頂級調用(腳本導入其餘部分)時嘗試了這一點,但它只是添加了另外25個文件查找,搜索__future__而沒有任何其他好處: - /。所有.pyc都在那裏,但搜索的順序是通用的:'* .so - > * module.so - > * .py - > * .pyc',所以它沒有區別。順便說它是絕對進口(沒有)。不管怎麼說,多謝拉! – estani 2013-03-18 10:50:58

+0

更正。是的,我想Python必須在Python文件之前查找C擴展,並且它必須找到'.py'文件來測試'.pyc'文件是否可能陳舊。我試圖給你選項,可以*避免查找。 – 2013-03-18 10:58:48

+0

確實,謝謝你!我還用一個只加載os並轉動'__future__'選項的文件對它進行了測試,但沒有任何區別。我想我可以嘗試調整PYTHONPATH,但我希望有一種方法可以將所有這些調用從一個python調用緩存到另一個...可以從給定路徑將模塊加載到內存中嗎?也許我可以預先加載它們... – estani 2013-03-18 11:25:34