我的Python程序非常慢!我怎样才能加快速度?难道我做错了什么?

时间:2011-12-24 13:19:10

标签: python performance

编辑:我运行了python profiler和两个最耗时的东西(这是在我决定注释掉webbrowser部分和Firefox部分代码之后,因为我知道它们将是最慢的部分.. 。),我程序中最慢的部分是re.findallre.compile以及(len)和(附加到列表)。

我不知道我是否应该立即将所有代码发布在这里,因为我对我的程序非常努力(即使它不太好),所以现在我只想问。 ..如何让我的Python程序更快?

我现在有3个嫌疑人,因为它太慢了:

  1. 也许我的电脑很慢

  2. 也许我的互联网速度太慢(有时我的程序必须下载网页的HTML,然后搜索html中的特定文本)

  3. 我的代码很慢(可能有太多循环?还有其他东西?我是新手,所以我不知道!)

  4. 如果有人能给我建议,我将不胜感激!

    谢谢!

    编辑:

    我认为我的代码使用了很多循环......另外,要使程序正常工作,您必须登录此网站:http://www.locationary.com/

    from urllib import urlopen
    from gzip import GzipFile
    from cStringIO import StringIO
    import re
    import urllib
    import urllib2
    import webbrowser
    import time
    from difflib import SequenceMatcher
    import os
    
    def download(url):
        s = urlopen(url).read()
        if s[:2] == '\x1f\x8b': # assume it's gzipped data
            with GzipFile(mode='rb', fileobj=StringIO(s)) as ifh:
                s = ifh.read()
        return s
    
    for t in range(3,39):
        print t
        s = download('http://www.locationary.com/place/en/US/Utah/Provo-page' + str(t) + '/?ACTION_TOKEN=NumericAction')
        findLoc = re.compile('http://www\.locationary\.com/place/en/US/.{1,50}/.{1,50}/.{1,100}\.jsp')
        findLocL = re.findall(findLoc,s)
        W = []
        X = []
        XA = []
        Y = []
        YA = []
        Z = []
        ZA = []
    
        for i in range(0,25):
            b = download(findLocL[i])        
            findYP = re.compile('http://www\.yellowpages\.com/')
            findYPL = re.findall(findYP,b)
            findTitle = re.compile('<title>(.*) \(\d{1,10}.{1,100}\)</title>')
            getTitle = re.findall(findTitle,b)        
            findAddress = re.compile('<title>.{1,100}\((.*), .{4,14}, United States\)</title>')
            getAddress = re.findall(findAddress,b)        
            if not findYPL:
                if not getTitle:
                    print ""
                else:
                    W.append(findLocL[i])
                b = download(findLocL[i])
                if not getTitle:
                    print ""
                else:
                    X.append(getAddress)
                b = download(findLocL[i])
                if not getTitle:
                    print ""
                else:
                    Y.append(getTitle)
        sizeWXY = len(W)
    
        def XReplace(text, dic):
            for i, j in dic.iteritems():
                text = text.replace(i, j)  
            XA.append(text)
    
        def YReplace(text2, dic2):
            for k, l in dic2.iteritems():
                text2 = text2.replace(k, l)  
            YA.append(text2)
    
        for d in range(0,sizeWXY):
            old = str(X[d])
            reps = {' ':'-', ',':'', '\'':'', '[':'', ']':''}
            XReplace(old, reps)
            old2 = str(Y[d])
            YReplace(old2, reps)
    
        count = 0    
        for e in range(0,sizeWXY):
            newYPL = "http://www.yellowpages.com/" + XA[e] + "/" + YA[e] + "?order=distance"
            v = download(newYPL)
            abc = str('<h3 class="business-name fn org">\n<a href="')
            dfe = str('" class="no-tracks url "')
            findFinal = re.compile(abc + '(.*)' + dfe)
            getFinal = re.findall(findFinal, v)
            if not getFinal:
                W.remove(W[(e-count)])
                X.remove(X[(e-count)])
                count = (count+1)
            else:
                for f in range(0,1):
                    Z.append(getFinal[f])
        XA = []
        for c in range(0,(len(X))):
            aGd = re.compile('(.*), .{1,50}')
            bGd = re.findall(aGd, str(X[c]))
            XA.append(bGd)
        LenZ = len(Z)
        V = []
        for i in range(0,(len(W))):
            if i == 0:
                countTwo = 0
            gda = download(Z[i-(countTwo)])
            ab = str('"street-address">\n')
            cd = str('\n</span>')
            ZAddress = re.compile(ab + '(.*)' + cd)
            ZAddress2 = re.findall(ZAddress, gda)
            for b in range(0,(len(ZAddress2))):
                if not ZAddress2[b]:
                    print ""
                else:
                    V.append(str(ZAddress2[b]))
                    a = str(W[i-(countTwo)])
                    n = str(Z[i-(countTwo)])
                    c = str(XA[i])
                    d = str(V[i])
                    #webbrowser.open(a)
                    #webbrowser.open(n)
                    m = SequenceMatcher(None, c, d)
                    if m.ratio() < 0.50:
                        Z.remove(Z[i-(countTwo)])
                        W.remove(W[i-(countTwo)])
                        countTwo = (countTwo+1)
    
        def ZReplace(text3, dic3):
            for p, q in dic3.iteritems():
                text3 = text3.replace(p, q)  
            ZA.append(text3)
    
        for y in range(0,len(Z)):
            old3 = str(Z[y])
            reps2 = {':':'%3A', '/':'%2F', '?':'%3F', '=':'%3D'}
            ZReplace(old3, reps2)
        for z in range(0,len(ZA)):
            findPID = re.compile('\d{5,20}')
            getPID = re.findall(findPID,str(W[z]))
            newPID = re.sub("\D", "", str(getPID))
            finalURL = "http://www.locationary.com/access/proxy.jsp?ACTION_TOKEN=proxy_jsp$JspView$SaveAction&inPlaceID=" + str(newPID) + "&xxx_c_1_f_987=" + str(ZA[z])
            webbrowser.open(finalURL)
            time.sleep(5)
    
        os.system("taskkill /F /IM firefox.exe")
    

2 个答案:

答案 0 :(得分:31)

程序缓慢时要做的第一件事就是识别瓶颈;事实上,你想要优化需要很长时间的事情,而不是那些可能实际上很快的事情。在Python中,最有效的方法是使用 Python profilers 中的一个,这是用于性能分析的专用工具。这是一个快速入门:

python -m cProfile -o prof.dat <prog> <args>

运行程序并将分析信息存储在prof.dat中。然后,

python -m pstats prof.dat

运行分析信息分析工具 pstats。重要的pstat命令包括:​​

sort time

按功能花费的时间对功能进行排序,您可以使用不同的密钥而不是timecumulative,...)来使用功能。另一个重要的命令是

stats

打印统计信息(或stats 10打印前10个最耗时的功能)。您可以使用?help <command>获取帮助。

优化程序的方法包括处理导致瓶颈的特定代码。您可以发布计时结果,也可以获得一些可以最有效优化的程序部分的更具体的帮助。

答案 1 :(得分:3)

一个好的起点是识别代码必须执行多次迭代的地方(例如,嵌套用于循环)或处理大量数据。在这些之前和之后放置打印声明,您将能够确定这是否需要多长时间。然后你可以看看为什么。

或者,如果它是一个小程序,只需发布​​整个内容。