0

我一直在尝试优化以下两个嵌套循环:

def startbars(query_name, commodity_name):

     global h_list
     nc, s, h_list = [], {}, {}
     query = """ SELECT wbcode, Year, """+query_name+""" 
                 FROM innovotable WHERE commodity='"""+commodity_name+"""' and

                 """+query_name+""" != 'NULL' """
     rows = cursor.execute(query)
     for row in rows:
         n = float(row[2])
         s[str(row[0])+str(row[1])] = n
         nc.append(n)
     for iso in result:
         try:
             for an_year in xrange(1961, 2031, 1):
                 skey = iso+str(an_year)
                 h_list[skey] = 8.0 / max(nc) * s[skey]
         except:
             pass

有任何想法吗?谢谢。

4

1 回答 1

5

您的代码不完整,因此很难给出好的建议,但是:

  1. 内循环不依赖外循环,所以把它拉出外循环。
  2. max(nc) 在第一个循环之后是一个常数,所以把它从循环中拉出来。

此外,您需要知道当前代码有多慢,以及您需要多快,否则您的优化可能会放错地方。

你的数据结构都搞砸了。也许列出这会更快:

def startbars(query_name, commodity_name):

    assert query_name in INNOVOTABLE_FIELD_NAMES

    ## TODO: Replace with proper SQL query
    query = """ SELECT wbcode, Year, """+query_name+""" 
             FROM innovotable WHERE commodity='"""+commodity_name+"""' and

             """+query_name+""" != 'NULL' """
    rows = cursor.execute(query)

    mapYearToWbcodeToField = {}
    nc = []
    global h_list
    h_list = {}

    for row in rows:
        n = float(row[2])
        wbCodeToField = mapYearToWbcodeToField.setdefault(int(row[1]),{})
        wbCodeToField[str(row[0])] = n
        nc.append(n)

    constant = 8.0 / max(nc)


    for (an_year,wbCodeToField) in mapYearToWbcodeToField.iteritems():
        if an_year < 1961 or an_year > 2031:
            continue

        for (wbCode,value) in wbCodeToField.iteritems():
            if wbCode not in result:
                continue

            skey = wbCode+str(an_year)
            h_list[skey] = constant * value

或者将所有检查移到第一个循环中:

def startbars(query_name, commodity_name):

    assert query_name in INNOVOTABLE_FIELD_NAMES

    ## TODO: Replace with proper SQL query
    query = """ SELECT wbcode, Year, """+query_name+""" 
             FROM innovotable WHERE commodity='"""+commodity_name+"""' and

             """+query_name+""" != 'NULL' """
    rows = cursor.execute(query)

    data = []
    maxField = None

    for row in rows:
        an_year = int(row[1])
        if an_year < 1961 or an_year > 2031:
            continue

        wbCode = str(row[0])
        if wbCode not in result:
            continue

        n = float(row[2])

        data.append((wbCode+str(an_year),n))
        if maxField is None or n > maxField:
            maxField = n

    constant = 8.0 / maxField

    global h_list
    h_list = {}

    for (skey,n) in data:
        h_list[skey] = constant * n
于 2010-10-01T16:22:32.400 回答