0

ここの人たちに簡単な質問をしたくはありませんし、グーグルで情報を探したと言いたいのですが、同じように直面した人たちから意見を聞きたいと思います。Pythonのwhileループは遅くなると言われています(http://wiki.python.org/moin/WhileLoop)。ループを1つだけ使用するスクリプトがありますが、それは非常に重要であり、実際には非常に遅くなります。私の最初のプログラムは100%CPU(デュアルコア!!!)を使用していました。ループにsleep()関数を導入したところ、CPU使用率が50%に低下しました。睡眠時間を増やし続けることはできませんが、実際には減らしたいと思います。とにかく、これをwhileループを高速化するための「トリック」はありますか?

(条件は、pyQt4で構築されたユーザーインターフェイスでボタンが押されたかどうかです)

4

2 に答える 2

1

リンクした参照は誤解を招く可能性があります。2つのサンプル間の速度差は最小限に抑えられ、ループ内で実際の作業が行われている場合でも通常は目立たなくなります。

ループが完了するまで、割り当てられた時間の100%を使用するのはループの性質ですループがひどく効率的であるか、非常に非効率的であるかは問題ではありません。sleepこれを回避する唯一の方法は、試行したものなど、待機させるOS関数を呼び出すことです。

最新のOSGUIがイベント駆動型である理由は、イベントをループで待つ必要がないためです。単一の関数を呼び出してメッセージを待機し、OSはメッセージが到着するまで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() 

startButtonを押したときにコードのこの部分を呼び出すまで(2%未満のCPUを使用)、GUIは正常に実行されます(もう一度押すまでチェックされたままになります)。

于 2013-02-20T12:34:52.290 に答える