有没有一种方法可以加快列表理解速度?

时间:2020-08-21 20:00:28

标签: python pygame

我已经使用Python / Pygame实现了“ Langtons循环”,并且“单元”的数组越大,程序运行的速度就越慢。 基本配置文件显示此行占用最多时间:

matchSet = [r for r in ruleSet if r[:5] == buff]

代码上下文:

surrBuff = []

surrBuff.append(str(self.dispBuff[y][x]) + str(self.dispBuff[y-1][x]) + 
                    str(self.dispBuff[y][x+1]) + str(self.dispBuff[y+1][x]) + 
                    str(self.dispBuff[y][x-1]))
surrBuff.append(str(self.dispBuff[y][x]) + str(self.dispBuff[y][x+1]) + 
                    str(self.dispBuff[y+1][x]) + str(self.dispBuff[y][x-1]) + 
                    str(self.dispBuff[y-1][x]))
surrBuff.append(str(self.dispBuff[y][x]) + str(self.dispBuff[y+1][x]) + 
                    str(self.dispBuff[y][x-1]) + str(self.dispBuff[y-1][x]) + 
                    str(self.dispBuff[y][x+1]))
surrBuff.append(str(self.dispBuff[y][x]) + str(self.dispBuff[y][x-1]) + 
                    str(self.dispBuff[y-1][x]) + str(self.dispBuff[y][x+1]) + 
                    str(self.dispBuff[y+1][x]))`

matchSet = []
for buff in surrBuff:
    #matchSet = [r for r in ruleSet if r.startswith(buff)]
    matchSet = [r for r in ruleSet if r[:5] == buff]

    if len(matchSet) > 0:
        break

ruleSet是一组规则-总共105条。
surrBuff是当前单元格周围的单元格集。

这个想法是在给定当前单元格值和可能的情况下,在ruleSet中找到匹配的规则 周围细胞的组合。

最大阵列大小约为40 * 50个单元格,一旦显示阵列达到20 * 50个单元格,我就会发现速度变慢。

给定我已经描述的设置,是否有更好的方法来找到匹配规则,或者这仅仅是我在这里尝试做的限制?

分析:

ncalls          tottime  percall  cumtime  percall filename:lineno(function)

  1    0.000    0.000   47.707   47.707 <string>:1(<module>)
2072040/465    2.531    0.000    5.054    0.011 copy.py:128(deepcopy)
  2046000    0.288    0.000    0.288    0.000 copy.py:182(_deepcopy_atomic)
26040/465    0.928    0.000    5.051    0.011 copy.py:200(_deepcopy_list)
    26040    0.021    0.000    0.030    0.000 copy.py:242(_keep_alive)
        1    0.063    0.063   47.707   47.707 langLoops2.py:100(mainLoop)
   509601    6.273    0.000   37.883    0.000 langLoops2.py:36(calcNewCellValue)
   835660   29.295    0.000   29.295    0.000 langLoops2.py:59(<listcomp>)
      465    0.338    0.001   38.222    0.082 langLoops2.py:85(updateCalcBuff)
      464    0.377    0.001    0.876    0.002 langLoops2.py:93(draw)
'''

2 个答案:

答案 0 :(得分:2)

如果只想知道是否至少有一场比赛,实际上并不需要整个列表。

    for buff in surrBuff:  
        if any(r[:5] == buff for r in ruleSet):
            break

any一旦找到要添加到列表中的元素,就会返回。

答案 1 :(得分:2)

如果您始终将规则的前五个元素进行比较,则可以根据这些规则创建字典,然后从该字典中查找匹配的规则。

DefaultBufferSize

此外,与此无关,您的个人资料输出中还有很多深层复制。通常,创建自己的专用复制逻辑要快得多,例如# create rule dict (just once, not within the loop) ruleDict = collections.defaultdict(list) for r in ruleSet: ruleDict[r[:5]].append(r) ... # get matchSet from dictionary matchSet = ruleDict[buff] 获取列表列表,而不是使用list(map(list, original))