0

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

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

4

2 回答 2

1

您链接到的参考具有误导性。如果在循环内进行任何实际工作,两个样本之间的速度差异将非常小,通常甚至不明显。

任何循环的本质都是在完成之前将使用 100% 的分配时间。循环是非常有效还是非常低效都没有关系。解决此问题的唯一方法是调用一些使其等待的操作系统函数,例如sleep您尝试过的。

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

于 2013-02-19T16:30:24.187 回答
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 时调用这部分代码(在我再次按下它之前一直处于选中状态)。

于 2013-02-20T12:34:52.290 回答