优化嵌套循环的方法通常取决于具体的情况,但有几种常见的技巧可以尝试。尽可能减少内部循环的迭代次数,这可以通过更有效的算法或数据结构来实现。如果内部循环中使用的值在外部循环中已经计算过,可以尝试在外部循环中计算并将结果存储起来,避免重复计算。下面是一个简单的示例,演示了如何通过优化来减少嵌套循环的计算量:
1、问题背景
在优化以下两个嵌套循环时遇到了一些困难:
代码语言:javascript复制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
希望找到一些优化思路来提高代码效率。
2、解决方案
优化建议:
- 将内部循环从外部循环中分离出来。因为内部循环并不依赖于外部循环,因此可以将其提取出来,这将简化代码结构并提高效率。
- 将
max(nc)
移出循环。max(nc)
在第一次循环后就是一个常量,因此可以将其移出循环以减少重复计算。 - 重新组织数据结构。优化后的代码使用了一个字典
mapYearToWbcodeToField
来存储数据,这使得查找更加高效。同时使用了一个列表nc
来存储所有值的最大值,这样就可以在一次循环中计算出constant
。
以下是优化后的代码:
代码语言:javascript复制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
或者,还可以将所有的检查都移到第一个循环中:
代码语言:javascript复制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
在这个示例中,原始的嵌套循环遍历了二维数组中的所有元素,并将每个元素乘以2后添加到结果列表中。优化后的版本避免了使用range(len(data))
和range(len(data[i]))
来遍历索引,而是直接遍历了二维数组中的每个元素。这种优化减少了重复计算,并使代码更简洁易读。