意外的Python算术行为

意外的Python算术行为,python,performance,encoding,decoding,Python,Performance,Encoding,Decoding,我正在用Python编写huffman编码器/解码器,在代码中遇到了一些意想不到的行为(至少对我来说是这样)。对文件进行编码很好,解码文件时会出现问题。以下是相关代码: def decode(cfile): with open(cfile,"rb") as f: enc = f.read() len_dkey = int(bin(ord(enc[0]))[2:].zfill(8) + bin(ord(enc[1]))[2:].zfill(8),2) # l

我正在用Python编写huffman编码器/解码器,在代码中遇到了一些意想不到的行为(至少对我来说是这样)。对文件进行编码很好,解码文件时会出现问题。以下是相关代码:

def decode(cfile):
    with open(cfile,"rb") as f:
        enc = f.read()
        len_dkey = int(bin(ord(enc[0]))[2:].zfill(8) + bin(ord(enc[1]))[2:].zfill(8),2) # length of dictionary
        pad = ord(enc[2]) # number of padding zeros at end of message
        dkey = { int(k): v for k,v in json.loads(enc[3:len_dkey+3]).items() } # dictionary
        enc = enc[len_dkey+3:] # actual message in bytes
        com = []
        for b in enc:
            com.extend([ bit=="1" for bit in bin(ord(b))[2:].zfill(8)]) # actual encoded message in bits (True/False)
    cnode = 0 # current node for tree traversal
    dec = "" # decoded message
    for b in com:
        cnode = 2 * cnode + b + 1 # array implementation of tree
        if cnode in dkey:
            dec += dkey[cnode]
            cnode = 0

    with codecs.open("uncompressed_"+cfile,"w","ISO-8859-1") as f:
        f.write(dec)
对于所有文件大小(测试大小为1.2MB、679KB和87KB),使用open(cfile,“rb”)as f的第一个
调用运行得非常快,但显著降低代码速度的部分是com中b的
循环。我做了一些计时,我真的不知道发生了什么

我已经对每个文件的整个
decode
功能进行了计时,如下所示:

87KB      1.5 sec
679KB     6.0 sec
1.2MB   384.7 sec
首先,我甚至不知道如何分配这种复杂性。接下来,我对有问题的循环的一次运行进行了计时,得到了行
cnode=2*cnode+b+1
需要2e-6秒,而
if-cnode在dkey
行需要0.0秒(根据OSX上的time.clock())。因此,似乎算术正在显著减慢我的程序。。。?我觉得这没道理


事实上,我不知道发生了什么,任何帮助都是非常受欢迎的

我找到了解决问题的方法,但事后我仍然感到困惑。我通过将
dec
更改为
[]
,然后将
dec+=dkey[cnode]
行更改为
dec.append(dkey[cnode])
解决了这个问题。这导致了以下几次:

87KB    0.11 sec
679KB   0.21 sec
1.2MB   1.01 sec

如你所见,这大大缩短了时间,因此在这方面,这是一次成功。然而,我仍然不明白为什么python的字符串连接似乎是这里的问题

很难说,它看起来更像是一个内存分配问题,而不是一个算术问题。需要检查的是:1)在进入循环之前打印com的长度-1.2MB文件是否会使com的长度成倍增加?2) 检查dkey的内容-此词典是否包含给定密钥的大量数据?也许在每次迭代时打印项目的大小,看看1.2MB文件是否有差异。3) 查看task manager/top,看看流程是否使用了大量内存。解码器是否可以正常工作?输出看起来像您认为应该的吗?特别是,解码后的输出是否与应该的一样长?回答@user2357112,是的,解码器按预期工作,输出文件与输入文件相同(编码前)。要回答@matt young,com的长度与文件大小成线性关系,
dkey
中的每个值都是一个字节,我已经仔细检查了,Python从运行40MB内存变为100MB内存(我在终端中运行),这是很奇怪的