意外的Python算术行为
我正在用Python编写huffman编码器/解码器,在代码中遇到了一些意想不到的行为(至少对我来说是这样)。对文件进行编码很好,解码文件时会出现问题。以下是相关代码:意外的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
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内存(我在终端中运行),这是很奇怪的