如何提高在Python中查找最常用字符串的性能?

时间:2013-09-08 15:01:18

标签: python performance algorithm sorting counter

我有大约30个文件,每个大小约为300MB。我在每个文件中都有一些我感兴趣的信息,例如用户名。现在我想找到使用正则表达式的用户名,然后找到最常用的用户名。这是我的代码:

rList=[]
for files in os.listdir("."):
    with open(files,'r') as f:
        for line in f:
            m=re.search('PATTERN TO FIND USERNAME',line)
            if m:
                rList.append(m.group())             
c=Counter(rList)
print c.most_common(10)

现在您可以看到,我将我找到的每个用户名添加到列表中,然后调用Counter()。这样就需要几分钟才能完成。我每次读完文件时都尝试删除c=Counter(rList)并调用c.update(),但它不会有任何不同,是吗?

那么,这是最好的做法吗?有什么方法可以改善性能吗?谢谢!

2 个答案:

答案 0 :(得分:1)

分析将向您显示,逐个循环遍历文件的每一行都会产生大量开销。如果文件总是在您指定的大小附近并且您可以花费内存,只需调用.read()就可以将它们放入内存中,然后使用更复杂的预编译regexp(将换行符考虑在内) )一次提取所有用户名。然后.update()你的反对象与匹配的正则表达式中的组。这将尽可能高效。

答案 1 :(得分:0)

如果你有记忆,那么:

  1. 使用mmap
  2. 尽可能使用隐式循环
  3. 以下片段应该很快但需要记忆:

    # imports elided
    
    patternString = rb'\b[a-zA-Z]+\b' # byte string creating a byte pattern
    pattern = re.compile(patternString)
    c = Counter()
    
    for fname in os.listdir("."):
        with open(fname, "r+b") as f:
            mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
            c.update(pattern.findall(mm))
    print(c.most_common(10))
    

    patternString应该是你的模式。