Python While Loop CPU要求

时间:2013-02-19 15:55:56

标签: python-2.7 while-loop

我不想用一个简单的问题来打扰这里的人,也告诉我用谷歌搜索信息,但我想得到那些面对同样的人的意见。据说,虽然python中的循环减慢了(http://wiki.python.org/moin/WhileLoop)。我有一个脚本只使用一个循环,但这是非常重要的,事实上它真的慢了下来。我的第一个程序是使用100%CPU(双核!!!)。我在循环中引入了sleep()函数,CPU使用率下降到50%。我不能只是不断增加睡眠时间,实际上我想减少它。无论如何,是否有任何'技巧'可以让这个循环更快?

(条件是在pyQt4上构建的用户界面上是否按下按钮)

2 个答案:

答案 0 :(得分:1)

您链接的引用具有误导性。如果在循环内部进行任何实际工作,两个样本之间的速度差异将是最小的,通常甚至不会引人注意。

任何循环的本质是它将使用100%的分配时间,直到完成为止。如果循环是有效的或非常低效的并不重要。解决这个问题的唯一方法是调用一些使其等待的OS函数,例如您尝试过的sleep

现代操作系统GUI是事件驱动的原因是您不必在循环中等待事件 - 您调用单个函数来等待消息,并且操作系统将CPU提供给其他人,直到消息到达。使用像Qt这样的框架,它将隐藏在所谓的消息循环中,并且您需要提供适当的框架挂钩以将事件路由到您自己的函数。

答案 1 :(得分:0)

我会研究你给我的信息。但是为了保持这里的讨论,代码的一部分正在放缓:

while self.startButton.isChecked():
    self.widget.canvas.ax2.clear()                                                 
    self.widget.canvas.ax2.set_xlabel('Sensor #')
    self.widget.canvas.ax2.set_yscale('log', basey = 10)                                   
    self.widget.canvas.ax2.set_xlim(0, num_sensors + 1) 
    self.widget.canvas.ax2.set_xticks(range(1, num_sensors + 1)) 
    self.widget.canvas.ax2.set_xticklabels(sensorLabel, fontsize = 10)
    measure, read_s = [], []                       
    t = round((time() - initialTime), 1)           
    for i in range(num_sensors):
        read = self.ser.readline().strip()  
        measure.append(read)
        read = float(read) 
        read_s.append(read) 
        self.widget.canvas.ax.plot(t, read, plot_array[i])
    self.widget.canvas.ax2.scatter(range(1, num_sensors + 1), read_s, c = log10(read_s), s = 100) 
    self.widget.canvas.ax2.set_ylim(bottom = .8 * min(read_s))                            
    f.write(str(t) + '\t' + '\t'.join(measure) + '\n')  
    self.widget.canvas.ax.legend(loc = 'center left', bbox_to_anchor = (2.2, 0.5), ncol = 1, fontsize = 10)
    self.widget.canvas.draw()                                                       
    QtCore.QCoreApplication.processEvents()                              
    sleep(.5)   # HERE IS THE SLEEP INTRODUCED
else:
    global last_read     
    last_read = measure   
    self.statusbar.showMessage('Idle')  
    f.close()          
    self.ser.write('C')  
    try:                          
        for i in range(1000):
            self.ser.timeout = .1
            a = self.ser.readline()
            self.statusbar.showMessage('Deleting reads in the serial buffer')  
            if a == 'Last':
                break 
    except:
        self.ser.close() 

GUI运行得很好(使用低于2%的CPU),直到我按下startButton(保持检查状态,直到我再次按下它)时,我会调用这部分代码。