2012-02-23 5 views
1

私は正確なランタイムを得るために、同時に1つのマシン上で2つのサブプロセスを実行することを検討していました。私はソフトウェアの2つのバージョンを比較しており、ランタイム、出力のばらつきなどの診断を実行しています。2つのpythonサブプロセスを実行し、ランタイムとstdoutを取得するにはどうすればいいですか?

元は同じ入力ファイルで両方のバージョンのソフトウェアを使用し、場所。古いバージョンと新しいバージョンは、argparserを通して取得されます。関数は各ソフトウェアコマンドにサブプロセスを使用し、出力は.communicate()によって取得されます。しかし、私が知っていることは、.communicate()はプロセスが終了するのを待っています。理想的には同時に両方のプロセスで.communicate()を使用して、同時に開始し、タイムアウトしたいのです。私が彼らのランタイムを知っている限り。

私の質問は、より簡潔には、それぞれが個別に実行され、同時に開始する2つのサブプロセスを実行する方法です。そして、彼らのランタイムとstdout、stderrをつかむ?

私の機能の相続人は簡単な例(ほんの一部のファイルでJavaのIM検査速度をふり):

def test(): 
    # Get start time   
    before = time.time() 
    cmd1 = ['java-1.0', 'blah'] 
    c1 = subprocess.Popen(cmd1, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    cmd2 = ['java-1.5', 'blah'] 
    c2 = subprocess.Popen(cmd2, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    # Start both processes at the same time?? 
    results = [c1.communicate(), c2.communicate()] 
    # Get total time taken 
    total = round(time.time()-before, 2) 
    # Print out the total time (I know its messy but its accurate) 
    print "%s:%s:%s" % (int(total/60/60), int(total/60), int(total)) 
    c1.stderr.close() 
    c2.stderr.close() 
    return results 

私がしたいもう一つのポイントが原因であれば、私は同時に実行するためにそれらを必要とするということです私は強力なリモートマシン上で仕事をしています(私はそうです)。そして、ジョブが実行されている間にワークロードを同じにして、別の時間に実行されたために1つのプロセスが速く終了しないようにします。

+0

よりもむしろふりを呼び出して、私達と直接的です。 2つの外部プログラムの速度を実際にテストしている場合、最良のアプローチは、単に実行する必要がある場合とは大きく異なります(ここで書いたものとはまったく異なります)。達成したいことをより詳細に共有してください。 –

+0

あなたのここでのラウンドの使用は理想的ではありません(実際には、ラウンドはまったく役に立ちません)。秒数を四捨五入したい場合は、 '%0.2f'フォーマット指定子などを使用してください。 –

+0

ラウンドのような組み込み関数が完全に無関係であることはわかりませんでしたが、それは実際に私の問題を解決することとは関係ありません。とにかく、もっと直接的なことは何を意味しますか?私は何かふりをするつもりはありません。はい、同じデータで2つの異なるバージョンのソフトウェアをテストし、その出力とスピードを比較したいと思います。具体的には、私はピカードの異なるバージョンをテストしています。新しいバージョンはおそらく最大5倍高速ですので、私はこれをテストしたいだけでなく、両方のバージョンが同じ結果をもたらすことを確認したいと思います! –

答えて

0

ランタイムを正確に取得しようとする場合は、テストを何度も実行して配布を確認する必要があります。ランタイムの中央値は適切な指標にする必要があります。両方を同時に実行しても、より正確な結果を得ることはできません。

0

ランタイムテストは、通常はアイドル状態のマシンで実行され、OSキャッシュの影響を知るために、さまざまな入力ファイルの有無にかかわらず何度も繰り返します。

同じリソースを競合する2つのプロセスを持つと、ではなく、がより正確な測定結果になります。

Pythonプログラムの高速化は、通常、適切なツールを使用する場合です。例えば。リストやその他の補完は通常ループより高速です。組み込み関数を使うとおそらくそれが優先されます。良い例は "an optimization anecdote"です。最適な最適化は、おそらく異なるアルゴリズムです。

CPythonの代わりにPyPyを使用すると、大幅な改善が得られる可能性があります。

+0

Pythonの最適化に関するあなたのアドバイスは、このスレッドでは外れている可能性があり、おそらくは有害です。 (リンクしているエッセイには真実がたくさんありますが、Pythonでスピードアップする方法についての実際的なアドバイスとして、それは古くなっています) –

+0

私の考え方は、原則として測定が完了しているということでしたコードが遅いと認識されるとき。結論のどの部分が古くなったと思いますか? –

0

この場合、プロセスに送信する入力がないので、Popen.communicate()を使用する必要はありません。 Popen呼び出し自体がプロセスを開始しますが、そのためにはPopen.communicate()は必要ありません。 Popen.poll()を使用して、Popen.communicate()を使用する代わりにプロセスが終了したかどうかを確認できます。

while True: 
    if c1.poll() is not None: 
     #Stop c1's timer 
    if c2.poll() is not None: 
     #Stop c2's timer 

あなたがstdoutとstderrをしたい場合は、2つのスレッドを生成し、その後Popen.communicate()を使用し、時間を記録することができます。

あなたはスレッドとして、このようなものを使用することができます。

def time_it(c): 
    results.append(c.communicate()) 
    times.append(time.time()) 

、スレッドを生成

results = [] 
times = [] 
threading.start_new_thread(time_it,(c1,)) 
threading.start_new_thread(time_it,(c2,)) 
+0

彼はこのプロセスのstdoutとstderrを収集しているので、あなたのテクニックは機能しません。 –

+0

どうすればこのように2つのスレッドを生成できますか? –

+0

私はこれのためのポストを更新しました。 – Phani