【发布时间】:2010-10-23 17:56:53
【问题描述】:
假设我想使用标准的socket 模块从套接字读取一行:
def read_line(s):
ret = ''
while True:
c = s.recv(1)
if c == '\n' or c == '':
break
else:
ret += c
return ret
s.recv(1) 到底发生了什么?每次都会发出系统调用吗?无论如何,我想我应该添加一些缓冲:
为了与硬件和网络现实进行最佳匹配,bufsize 的值应该是 2 的相对较小的幂,例如 4096。
http://docs.python.org/library/socket.html#socket.socket.recv
但是编写高效且线程安全的缓冲似乎并不容易。如果我使用file.readline() 会怎样?
# does this work well, is it efficiently buffered?
s.makefile().readline()
【问题讨论】:
-
"每次都会发出系统调用吗?"为什么这很重要?
-
因为系统调用很慢。最好先获取一大块数据(如果可用),然后对其进行处理。现在我知道 Python 并不是特别快,也许这并不重要。但是文档说最好还是按大块阅读。
-
请注意,使用
+=构建字符串是一个禁忌,因为它可能是二次的,而使用追加使用str.join构建列表始终是线性的。 -
@MikeGraham 吹毛求疵,我知道,但是增加一个列表将是平均线性的,除了当后备数组填满并且新数组被分配和复制时。所以是的,线性时间,除了偶尔的打嗝
-
@Miquel,我描述的操作将是线性的。附加项目通常是恒定的(并且平均而言是恒定的)。偶尔追加一个项目是线性的,但这些以这样一种方式展开,以至于添加 n 个项目是线性的。