urllib.urlopen()是如何工作的?
我们来考虑一个大文件(大约100MB)。假设这个文件是基于行的(也就是一个文本文件,每行相对较短,大约80个字符)。如果我使用内置的 open()
或 file()
,这个文件会以一种“懒惰”的方式加载。也就是说,当我执行 aFile.readline()
时,只有一部分文件会被加载到内存中。那么,urllib.urlopen()
是不是也做类似的事情(使用磁盘缓存)呢?
使用 urllib.urlopen().readline()
和 file().readline()
之间的性能差异有多大呢?假设文件在本地。当我先用 urllib.urlopen()
打开它,然后再用 file()
打开时,使用 readline()
循环读取文件时,性能和内存消耗的差异会有多大呢?
通过 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)
urllib.urlopen()是不是也有类似的功能(使用磁盘缓存)?
其实是操作系统在做这件事。当你使用像 urllib
这样的网络接口时,操作系统和网络卡会负责把数据分成小块,然后通过网络发送出去,同时也会接收进来的数据包。这些数据包会被存储在缓存里,这样应用程序就可以不需要关心这些数据包的细节,假装自己是在发送和接收连续的数据流。
使用
urllib.urlopen().readline()
和file().readline()
的性能差别有多大?
这两者很难直接比较。对于 urllib
来说,性能主要取决于网络的速度和服务器的速度。即使是本地服务器,也会有一些额外的处理开销,所以通常来说,从网络接口读取数据会比直接从文件读取要慢。
如果想要真正比较性能,你需要写一个测试脚本来测量。不过,为什么要这么做呢?因为这两者的用途不同,不能简单地互相替换。
通过
urllib.urlopen()
打开的文件,最好的处理方式是什么?逐行处理快吗?还是说先把一堆行(大约50行)加载到列表里再处理?
由于网络速度是瓶颈,尽早处理数据可能是个好主意。这样,操作系统可以在“后台”缓存更多的进来的数据。
在处理之前把行缓存到列表里是没有意义的。你的程序会在那儿等着,等着足够的数据到来,而其实它可以先做一些有用的事情。