我最近遇到了一个奇怪的问题,希望这里有人能帮我。我在Ubuntu12.04中使用Python2.7,python和操作系统都是64位的。
在我的代码中,我需要不断地将传入的数据流附加到字节数组中,我使用self.data+=incomingdata来实现这一点,其中incomingdata是我从硬件设备接收的数据。稍后,我将对字节数组进行解包,以解析接收到的数据。附加和解析操作都受到锁的保护。
这里的问题是,当我使用"+="来附加字节流时,数据在某些点上似乎已损坏(不一致)。没有内存使用错误,没有溢出等。我监控了程序的内存使用情况,看起来不错。
然后,当我将"+="更改为cStringIO.write以实现追加操作时,没有任何问题,尽管它似乎比"+="操作慢。
有人能告诉我当cStringIo.write和"+="用于操作字节流时,它们之间的确切区别是什么吗?"+="操作是否会导致任何潜在问题?
与其使用+=
,不如创建一个列表并将数据附加到列表的末尾。当所有数据都被提取后,您可以执行''.join(list)
来创建单个字符串。这将更好地预成型,因为串连接是低效的。
当您连接两个字符串时,python必须分配新的内存来存储新字符串。如果你要进行大量的串联,这可能会非常慢。随着字符串大小的增长,执行串联所需的时间也会增加,如果以这种方式获取大量数据,可能会使处理器不堪重负,并导致其他操作延迟。
当我构建一个重新组装TCP流的python进程时,我也遇到了类似的问题。我捕获的每一个数据包都是使用串联添加到字符串中的。一旦字符串增长到几MB,我使用的数据包捕获库就开始丢弃帧,因为CPU花了很多时间进行字符串连接。一旦我改为使用列表并在最后加入结果,问题就消失了。
cStringIO.write
没有这个问题的原因是它通过在内存中创建一个虚拟文件来操作,并将数据附加到此文件中,而不必每次为新字符串重新分配空间。