2011-09-27 12 views
3

我正在開發一個具有非常積極的緩存的Web應用程序。幾乎Web應用程序的每個組件:視圖,部分視圖,控制器輸出,磁盤加載,REST-API調用,數據庫查詢。所有可以緩存的任何級別的內容都被緩存,全部使用裝飾器。Python:防止緩存放慢我的速度

當然,這個速度非常快,因爲絕大多數的HTML代包含純函數,而且很少有來自磁盤/ REST API的負載。此外,我執行的少量磁盤加載/數據庫查詢/ REST API查詢也被緩存直到無效,所以除非只是更改,它們也非常快。因此,所有事情都很快,但有一個問題:所有這些東西都被緩存在內存中,在我的WSGI進程中的一個巨大的全局字典中,因此可以直接存儲而不需要序列化。一旦我開始將東西放入memcached中,緩存命中所花費的時間不會發生太大的變化,但是將東西放入緩存開始需要更長的時間。一般來說,沒關係,但每個頁面的初始「填充緩存」生成時間大約爲900ms(考慮到從磁盤讀取多少個平面文件,這已經相當快了)約爲9000ms。作爲參考,一旦緩存被預熱,生成一個任意頁面需要10毫秒。

剖析代碼,絕大多數時間都是cPickle。所以問題是,我怎樣才能讓這個更快?有沒有任何內存緩存可以直接將我的對象傳遞給序列化?或者某種方式可以更快速地緩存我的大堆物體?我可以不使用持久的memcached,但是隨後我的表現(或缺乏)將成爲Apache/WSGI流程管理者的心血結晶。

+0

你使用cPickle協議2嗎?你有沒有試過[marshal](http://docs.python.org/library/marshal.html)? – jterrace

+0

我正在使用cPickle協議2.我認爲元帥不適用於用戶定義的類嗎? –

回答

3

如果您序列化Python對象,而不是簡單的數據類型,並用鹹菜,嘗試cPickle.HIGHEST_PROTOCOL:

my_serialized_object = cPickle.dumps(my_object, cPickle.HIGHEST_PROTOCOL) 

默認的協議與舊版本的Python兼容的,但你可能不要我不在乎。

我剛剛做了一個簡單的1000基準字典的基準測試,它的速度幾乎要快一個數量級。

更新:由於您似乎已經使用最高協議,您將不得不做一些額外的工作來獲得更多的性能。以下是我會在這一點上做的:

  1. 確定哪些類是最慢的鹹菜

  2. 創建一對類中的方法來實現更快的序列化方法,說_to_string()和_from_string(一個或多個)。實際的序列化可以根據對象的含義以及將如何使用來定製。例如,一些對象可能實際上只包含一個簡單的字符串,比如一個渲染的模板,有些實際上可能會以JSON的形式發送到瀏覽器,在這種情況下,您可以簡單地序列化爲JSON並直接提供。使用timeit module以確保您的方法實際上更快

  3. 是在你的裝飾,檢查hasattr(對象,「_to_string」),並使用它,如果它存在

此方法可以解決最差的課程,並且對代碼基礎的干擾最小。

+0

元帥更快 – jterrace

+0

對於本機類型,是的,但它不支持對象,而且OP似乎暗示他正在緩存對象。 –