2010-10-01 103 views
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 

任何想法?谢谢。

+0

这是你的实际代码? – SilentGhost 2010-10-01 16:19:33

+2

您可能想使用绑定参数来解决sql注入问题,并且我怀疑!='NULL'而不是IS NOT NULL – 2010-10-01 16:29:02

+0

这是我的实际代码。 sql查询需要很长时间,但循环也需要一段时间。我真的不知道可以做些什么。 – relima 2010-10-01 16:29:09

回答

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 
+0

哦!我的天啊!!它开箱即用(我不得不删除断言行),但它使程序立即做出反应!非常感谢你。它将时间缩短到原始时间的1/8!哇! – relima 2010-10-01 17:09:02

+1

不要删除断言...而是将INNOVOTABLE_FIELD_NAMES定义为创新表的字段列表。 – 2010-10-01 17:14:24