迭代一个大字符串并检查字典性能中子字符串的成员资格

时间:2017-12-18 04:22:28

标签: python string performance

我目前正在python中实现霍夫曼编码,我已经完成了它,但我想提高它的效率。

这是我用来获取原始文件内容的方法

def getDecodedFile(self, text, codes):
        code = ""
        origin = []        
        for ch in text:
            code += ch
            if code in codes:
                origin.append(codes[code])
                code = ""
        bCodes = bytes(origin)
        return bCodes

text大字符串是codes是霍夫曼代码的字典(Key是代码的字符串,值是0到255之间的int)

我尝试使用''.join(somelist)代替code += ch但结果却慢了。目前,使用len(text) = 13972363执行此方法需要3秒钟,最短代码长度为6

数据示例:

text = "0100101110111"

codes = {'0': 65, '100': 66, '101': 67, '110': 68, '111': 69}

这将导致origin = [65,66,67,68,69]

我很感激任何使我的代码有效的建议。

2 个答案:

答案 0 :(得分:2)

据我所知,你可以做的一件事就是当你这样做时:

code += ch
if code in codes:
    origin.append(codes[code])
code = ""

具体而言,每次修改if code in codes:时都会检查code。例如,对于长度为 k 的代码,您将最终执行O(1 + 2 + 3 + ... + k )= O(0.5 * < em> k * k +1)= O( k ²)此处的操作。相反,您应该通过构建一个霍夫曼树并在树上执行单个O( k )遍历来解码您的代码(从根目录开始,并读取单个1或1)来预处理codes每次0并沿着相应的子边缘向下;一旦你按下一个字母,在解码的消息中输出它并移回到树的根部)。这不仅明确节省了支票if code in codes:的时间复杂度,而且还避免了每次执行code时重建字符串code += ch

除此之外,我不确定你是否可以进一步优化。我想知道将每个单独的解码字母转换为byte并附加到输出列表是否会更快,而不是将字母解码为列表然后通过bytes(origin)转换列表?

答案 1 :(得分:2)

最大的性能提升将来自使用像trie这样的东西存储你的霍夫曼树。这将允许您一次下降一个级别,这将消除字符串连接或重复检查存在的需要。