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

jac*_*501 3 python performance

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

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

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

  1. 也许我的电脑很慢

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

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

如果有人能给我建议,我将非常感激!

谢谢!

编辑:

我认为我的代码使用了很多循环...另外,对于程序工作,你必须登录到这个网站: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")
Run Code Online (Sandbox Code Playgroud)

Eri*_*got 32

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

python -m cProfile -o prof.dat <prog> <args>
Run Code Online (Sandbox Code Playgroud)

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

python -m pstats prof.dat
Run Code Online (Sandbox Code Playgroud)

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

sort time
Run Code Online (Sandbox Code Playgroud)

它按照在它们中花费的时间对函数进行排序,并且可以使用不同的键而不是time(cumulative,...)来使用它们.另一个重要的命令是

stats
Run Code Online (Sandbox Code Playgroud)

哪些打印统计(或stats 10打印前10个最耗时的功能).您可以获得帮助?,或help <command>.

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

  • @ jacob501:对于`re.compile`,你可以把汇编*放在循环之外*.您可以考虑的另一件事是将代码分成各种功能:分析器将各个功能分开; 通过将代码拆分为函数,您可以获得有关应优化代码部分的更详细信息(大多数情况下使用的`findall()`函数在哪里?等等).然后,您可以考虑如何优化该部分(并可能在StackOverflow或StackExchange上的Code Review上询问有关此问题的特定问题). (2认同)