Performance 使算法在多个列表上运行更快

Performance 使算法在多个列表上运行更快,performance,python-2.7,nested-loops,Performance,Python 2.7,Nested Loops,我正在编写一些具有嵌套循环的函数,当涉及大列表时,它的运行速度非常慢 def get_resolved(urllist, generated_urls, layout): result = {} for url in urllist: tmp_result = [] for gurl in generated_urls[url]: if gurl in resolved[layout]: tm

我正在编写一些具有嵌套循环的函数,当涉及大列表时,它的运行速度非常慢

def get_resolved(urllist, generated_urls, layout):
    result = {}
    for url in urllist:
        tmp_result = []
        for gurl in generated_urls[url]:
            if gurl in resolved[layout]:
                tmp_result.append(gurl)
        result[url] = tmp_result
    return result
我在这个函数中有三个列表,一个包含大约5000个域名的列表URL列表,一个包含大约500000个项目的生成URL列表,这也是文本,然后第三个列表解析[布局]。最后一个列表来自一个全局字典。这一个也包含平均10000个项目

我想返回一个结果字典,它只包含该特定url(也在已解析的[layout]列表中)生成的\u url中的项目

问题是这个嵌套循环执行起来大约需要一个小时。这太慢了,因为我要做30次左右。我看不出如何使这更有效。有人知道我怎么做吗

我还在这个脚本上运行cProfile,这让我看到上面的脚本是如此的慢。 这是输出的顶部部分:

Sat Nov 29 17:09:10 2014    profile_difflayouts

         2684341 function calls (2684295 primitive calls) in 101.069 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.006    0.006  101.069  101.069 DiffLayouts.py:1(<module>)
        1    0.001    0.001  101.055  101.055 DiffLayouts.py:13(main)
       18    0.001    0.000   95.898    5.328 DiffLayouts.py:62(process_data)
       36   95.712    2.659   95.712    2.659 DiffLayouts.py:149(get_resolved)
        1    0.001    0.001   79.703   79.703 DiffLayouts.py:30(check_alexa_list_single)
        1    0.000    0.000   16.198   16.198 DiffLayouts.py:42(check_alexa_list_combined)
        3    0.950    0.317    5.152    1.717 DiffLayouts.py:136(filter_domainnames)
  1017314    2.182    0.000    2.182    0.000 {method 'search' of '_sre.SRE_Pattern' objects}
   775796    1.561    0.000    1.561    0.000 {method 'findall' of '_sre.SRE_Pattern' objects}
       75    0.240    0.003    0.240    0.003 {method 'read' of 'file' objects}
       75    0.115    0.002    0.115    0.002 {method 'splitlines' of 'str' objects}
我希望这能得到充分的解释。如果你不明白我在这里想做什么,就问我


谢谢

从配置文件中可以看出,如果解析了[layout]中的x,您将花费所有时间检查元素的成员身份

现在,列表并不是存储不可变的对象集的最有效的方法,这些对象只需要支持搜索改用集合。考虑这个微基准:

import random
import time
import sys

size_url      = 10000
size_resolved = 10000

random.seed(time.time()) 

url = [ random.randint(1,sys.maxint) for x in xrange(size_url)]
resolved = [ random.randint(1,sys.maxint) for x in xrange(size_resolved)]

a = time.time()
intersection = [ x for x in url if x in resolved ]
print "Search in list:",time.time() - a

resolved = set(resolved)

a = time.time()
intersection = [ x for x in url if x in resolved ]
print "Search in set:",time.time() - a
这是我在笔记本电脑上得到的输出:

Search in list: 1.89044713974
Search in set: 0.00117897987366
因此,请按以下方式修改代码:

def get_resolved(urllist, generated_urls, layout):
    result = {}
    for url in urllist:
        result[url] = [x for x in generated_urls[url] if x in set(resolved[layout])]
    return result

你能把所有三个输入都加上一个小样本吗?我的整个过程从大约30小时改进到大约4分钟。这是巨大的。非常感谢。但我第一次尝试的一件事是转换到一组解析列表,因为这是在这个函数中完成的,所以需要花费很长的时间来反复转换。这就是为什么我在创建列表并将其存储在已解析字典中时设置该列表的进程。现在它只需要4分钟就可以工作了。
def get_resolved(urllist, generated_urls, layout):
    result = {}
    for url in urllist:
        result[url] = [x for x in generated_urls[url] if x in set(resolved[layout])]
    return result