像這樣隱藏進口是一種優化;每當考慮是否優化時,驗證提議的優化是否真的有效。
我們首先考慮datetime
的具體示例。這裏有一個簡單的應用程序:
import sys
import webapp2
class Handler(webapp2.RequestHandler):
def get(self):
if 'datetime' in sys.modules:
self.response.write('The datetime module is already loaded.\n')
else:
self.response.write('The datetime module is not already loaded\n.')
self.response.write('%d modules have been loaded\n' % len(sys.modules))
count = sum(1 for x in sys.modules.values() if '/lib64' in repr(x))
self.response.write('%d standard library modules have been loaded\n' % count)
gcount = sum(1 for x in sys.modules.values() if 'appengine' in repr(x))
self.response.write('%d appengine modules have been loaded\n' % gcount)
application = webapp2.WSGIApplication([('/', Handler)])
如果我們參觀「/」的網址,我們看到這樣的輸出:
datetime模塊已經加載。
706模塊已經載入
95標準庫模塊已經載入
207的AppEngine模塊已經載入
即使在這個最小的應用程序,datetime
已經由SDK進口*。一旦Python導入了一個模塊,進一步的導入只花費一次字典查找,所以隱藏導入沒有任何好處。由於SDK已經導入了95個標準庫模塊和207個SDK模塊,因此隱藏導入常用標準庫或SDK模塊的可能性不大。
這留下了導入應用程序代碼的問題。處理程序可以延遲加載通過聲明他們作爲路線字符串,這樣直到路線參觀他們沒有進口:
app = webapp2.Application([('/foo', 'handlers.FooHandler')])
這種技術允許優化啓動時間不隱藏在類或方法的進口,你應該找這是必要的。
其他答案指出,延遲加載的代價可能是意外的運行時錯誤。此外,如果您選擇隱藏導入,它也會降低代碼可讀性,可能導致結構性問題,例如掩蓋循環依賴性,併爲經驗較少的開發人員設置一個不好的示例,他們可能會認爲隱藏導入是慣用的而不是優化。
因此,考慮以這種方式優化時:
- 驗證優化是必要的:不是所有的應用程序都需要絕對最大性能
- 驗證正確的問題正在得到解決;在App Engine上的RPC調用往往主宰響應時間
- 配置文件以驗證優化是有效
- 考慮代碼的可維護性
*費用依託SDK的sys.modules
是相似的我希望雲運行時是一個合理的假設。