在Python中强制传递引用

时间:2011-07-21 13:05:27

标签: python string reference

男孩我不理解python pass-by-reference问题...我创建了非常有用的“unpacker”类,我将它传递给需要从中解压缩的各种对象,但是它的速度非常慢。 ,我可以告诉它每次传递BU对象时都会制作binaryStr的副本。我知道这一点,因为如果我将BU分成更小的块,它运行速度快100倍(我最初使用它来保存16MB文件I / O缓冲区)

所以我的问题是,为什么该成员没有通过引用传递,有没有办法强迫它?我很确定BU对象本身是通过引用传递的(因为我的代码工作),但速度表明复制了.binaryStr对象。是否有一些我想念的更微妙的东西?

class BinaryUnpacker(object):
    def __init__(self, binaryStr):
        self.binaryStr = binaryStr
        self.pos = 0

    def get(self, varType, sz=0):
        pos = self.pos
        if varType == UINT32:
            value = unpack('<I', self.binaryStr[pos:pos+4])[0]
            self.pos += 4
            return value
        elif varType == UINT64:
            value = unpack('<Q', self.binaryStr[pos:pos+8])[0]
            self.pos += 8
            return value
        elif varType == VAR_INT:
            [value, nBytes] = unpackVarInt(self.binaryStr[pos:])
            self.pos += nBytes
        ....

对此的用例类似于:

def unserialize(self, toUnpack):
    if isinstance(toUnpack, BinaryUnpacker):
        buData = toUnpack
    else:  # assume string
        buData = BinaryUnpacker(toUnpack)

    self.var1    = buData.get(VAR_INT)
    self.var2    = buData.get(BINARY_CHUNK, 64)
    self.var3    = buData.get(UINT64)
    self.var4obj = AnotherClass().unserialize(buData)

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:4)

在对字符串进行切片以获取子字符串时会生成副本。例如:

[value, nBytes] = unpackVarInt(self.binaryStr[pos:])

这将创建从索引pos到结尾的字符串副本,这可能需要一段时间才能生成长字符串。如果你可以在获取子字符串之前确定实际需要的字节数,然后使用self.binaryStr[pos:pos+nBytes],因为获取一个小的子字符串相对较快。

请注意,时间仅取决于子字符串的长度,因此无论self.binaryStr[pos:pos+4]的长度如何,self.binaryStr都应占用大致相同的时间。

答案 1 :(得分:3)

我没有深入查看您的代码,但是可以使用buffer()访问公开memoryview objects方法(例如字符串)的类型,而无需复制数据。 Here's the relevant documentation为此。

您可以使用memoryview对象而不是切割字符串:这样您就可以绕过当前代码的耗时过程。

前几天我问a question这个可能对你有用的事情。

答案 2 :(得分:0)

我认为仅靠速度判断是不合适的。你说你可以告诉你正在复制字符串,因为如果你将它分成更小的块,它运行得更快。但是你没有详细介绍的unpack()函数的运行时间也可能取决于数据大小。

此外,切片

等字符串
unpack('<I', self.binaryStr[pos:pos+4])[0]

将创建新的字符串对象,因为字符串是不可变对象。