优化两个简单的嵌套循环

时间:2010-10-01 16:16:31

标签: python nested-loops optimizer-hints

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

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

有什么想法吗?感谢。

1 个答案:

答案 0 :(得分:5)

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

  1. 内部循环不依赖于外部循环,因此将其拉出外部循环。
  2. max(nc)是第一次循环后的常量,因此将其拉出循环。
  3. 此外,您需要知道当前代码有多慢,以及您需要多快,否则您的优化可能会放错位置。

    您的数据结构全都搞砸了。也许某些列表会更快:

    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