2011-08-26 57 views
2

讓我們考慮一個大文件(〜100MB)。讓我們考慮這個文件是基於行的(一個文本文件,相對較短的行~80個字符)。 如果我使用內置的open()/file()該文件將被加載到lazy manner。 I.E.如果我做aFile.readline()只有一個文件塊將駐留在內存中。 urllib.urlopen()是否做了類似的事情(使用磁盤上的緩存)?urllib.urlopen()如何工作?

urllib.urlopen().readline()file().readline()之間的性能差異有多大?讓我們考慮一下這個文件位於localhost上。一旦我用urllib.urlopen()打開它,然後用file()打開它。當我使用readline()循環播放文件時,性能/內存消耗有多大?

處理通過urllib.urlopen()打開的文件的最佳方式是什麼?逐行處理它會更快嗎?或者我應該加載一堆行(〜50)到列表中,然後處理列表?

回答

1

urllib.urlopen()是否做了類似的事情(使用磁盤上的緩存)?

操作系統確實。當您使用網絡API(如urllib)時,操作系統和網卡將執行將數據拆分爲通過網絡發送的小數據包以及接收傳入數據包的低級工作。這些數據存儲在緩存中,以便應用程序可以抽象出數據包概念並假裝它將發送和接收連續的數據流。

urllib.urlopen().readline()file().readline()之間的性能差異有多大?

很難比較這兩者。對於urllib,這取決於網絡的速度以及服務器的速度。即使對於本地服務器,也存在一些抽象開銷,所以通常從網絡API讀取比從文件直接讀取要慢。

對於實際的性能比較,您必須編寫測試腳本並進行測量。但是,你甚至爲什麼打擾?你不能用另一個替換另一個,因爲它們用於不同的目的。

處理通過urllib.urlopen()打開的文件的最佳方式是什麼?逐行處理它會更快嗎?或者我應該加載一堆行(〜50)到列表中,然後處理列表?

由於瓶頸是網絡速度,因此一旦得到數據就可能是一個好主意。這樣,操作系統可以「在後臺」緩存更多的傳入數據。

在處理它們之前緩存列表中的行是沒有意義的。你的程序只是坐在那裏等待足夠的數據到達,而它可能已經做了一些有用的事情。

2

open(或file)和urllib.urlopen看起來像他們或多或少在那裏做同樣的事情。urllib.urlopen是(基本上)創建socket._socketobject然後調用makefile方法(該方法的內容包括下面)

def makefile(self, mode='r', bufsize=-1): 
    """makefile([mode[, bufsize]]) -> file object 

    Return a regular file object corresponding to the socket. The mode 
    and bufsize arguments are as for the built-in open() function.""" 
    return _fileobject(self._sock, mode, bufsize)