如何优化Python for循环以使其运行更快

时间:2013-08-04 03:45:54

标签: python optimization raspberry-pi led

我正在尝试使用overlocked(“Turbo”模式)Raspberry Pi和两个MCP23017 i2c端口扩展器来复用63个RGB LED阵列。我遇到的问题是LED闪烁很多。

每个LED基本上是三个LED,其中一个具有共阳极。因此,我将它们视为单独的LED。因此,在14x14矩阵中,我有效地拥有189个LED,而不是63个LED。它由以下人员创建:

pin_array=[[0]*14 for i in range(14)]

然后矩阵中的每个条目都填充1表示LED应该打开,或者如果它应该关闭则填充0。要循环打开/关闭每个LED,我使用以下代码:

#Example continous loop
while (1==1):
    #Cycle through pins and turn on/off appropriate LEDs
    for row_index, row in enumerate(pin_array):
        #Power on row
        mcp1.output(row_index,1) #for mcp1 a value of 1 is On
        for col_index, column in enumerate(row):
            #If the value is 1 turn on the LED then turn it off
            if column==1:
                mcp2.output(col_index,0) #for mcp2 a value of 0 is On
                mcp2.output(col_index,1)
        #Power off row
        mcp1.output(row_index,0)

有没有办法改进/优化上面的代码,使其运行得更快,以免闪烁消失?

更新:我尝试过使用zero.zero.seven,user2357112和kindall提供的一些优化和建议,最后得到了这样的结论:

last_row=13
last_col=13
while 1:
    row=0
    #Cycle through pins and turn on/off appropriate LEDs
    while row<14:
        col=0
        #Power on row
        mcp1.output(row,1) #for mcp1 a value of 1 is On
        while col<14:
            if pin_array[row][col]==1:
                mcp2.output(last_col,1) #for mcp2 a value of 0 is On
                mcp2.output(col,0)
                last_row=row
                last_col=col
            col+=1
        mcp1.output(row,0)
        row+=1

我唯一可以判断闪烁的方法是悲伤的。在我看来,优化和激活计划的变化对闪烁没有任何明显的变化。

2 个答案:

答案 0 :(得分:0)

我认为这些是您需要的微观优化

#Example continous loop
#these are optional
#pin_array_len = len(pin_array)
#i_len = len(pin_array[0])
while True:
    i = 0
    #Cycle through pins and turn on/off appropriate LEDs
    while i < 14:
        j = 0
        #Power on row
        mcp1.output(i,1) #for mcp1 a value of 1 is On
        while j < 14:
            #If the value is 1 turn on the LED then turn it off
            if pin_array[i][j]==1:
                mcp2.output(j,0) #for mcp2 a value of 0 is On
                mcp2.output(j,1)
            j += 1
        #Power off row
        mcp1.output(i,0)
        i += 1

答案 1 :(得分:0)

我认为你最大的问题是你几乎在打开LED时关闭了LED。由于环路的开销,LED将花费更少的时间而不是关闭。避免这种情况的一种方法可能是记住您打开的最后一列,并在打开下一个LED之前将其关闭,而不是相反。

您还可以进行一些微观优化。例如,不是强制Python每次通过1循环将1while进行比较,而是执行while True甚至是while 1更快(因为True是必须查找的全局名称)。这不会产生很大的不同,因为这种比较通常不会发生。

通过一些技巧,您可以将内部循环编写为生成器表达式。虽然这对可读性不是很好,但您可能会获得更好的性能。此外,您可以尝试预先生成行和列索引的列表,然后迭代索引,而不是使用enumerate()进行迭代。当然,您需要对此进行分析以确定它是否真的更快。

但是,你永远不会从CPython中获得真正的高性能。幸运的是,PyPy 2.1在ARM上运行,可以部署在Raspberry Pi上;你可以尝试一下。