Pythonのstdoutバッファサイズを増やす
Nov 26 2020
Pythonでstdout
バッファサイズを8182から増やす方法や、実際に呼び出すまでフラッシュを遅らせる方法はありますflush
か?
私が試したがうまくいかないこと:
- バッファに直接アクセスできるため、Windowsでこの問題を回避できます(たとえば、この投稿への回答を参照してください)。しかし、これはUnixでは機能しません。
buffer
コンストラクターに渡すことでファイルのバッファーサイズを増やすことができますが、stdout
既に構築されています。- バッファリング(
python -u
)をオフにすると、明らかに事態が悪化します。 - 一時バッファを使用すると、同じ問題が発生し
stdout
ます。一時バッファから8192バイトがコピーされるたびにフラッシュされます。
理論的根拠:ここでの目的は、コンソールのちらつきを減らすことです。たとえば、Cで試したりPythonでWindows APIを使用したりすると、この質問に従ってすべてをバッファリングすることは実際に機能しますが、Pythonの8182の制限により、Unixでは回避できない問題が発生しているようです。
回答
1 blhsing Nov 27 2020 at 05:29
として利用可能な生のstdoutストリームsys.stdout.buffer
を、より大きなバッファサイズでio.BufferedWriter
ラップしてから、結果のバッファリングされたバイナリストリームをバッファリングされたテキストストリームとして次のようにラップできますio.TextIOWrapper
。
import io
import sys
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))
stdoutのバッファサイズを100000に増やして、手動フラッシュが呼び出されるまで2つの10000文字の長さの印刷出力をフラッシュしないようにする効果のデモンストレーションを次に示します。
import io
import sys
import time
print('Original buffer size:', io.DEFAULT_BUFFER_SIZE)
for large_buffer in False, True:
if large_buffer:
print('Increasing buffer size...')
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, 100000))
for i in range(2):
time.sleep(2)
print(str(i * 2) * 10000)
time.sleep(2)
print(str(i * 2 + 1) *10000)
print(f'Flush #{i + 1}')
sys.stdout.flush()
デモ: https://repl.it/@blhsing/UnkemptGullibleDecompiler
1 cz Nov 27 2020 at 16:39
答えを見つけました、実際には非常に簡単です:
my_stdout = open( 1, "w", buffering = 100000 )
1
はfileno
ですstdout
。sys.stdout = my_stdout
デフォルトのprint
ターゲットに変更を加えるために使用できます。- 私はこれをUnixでのみテストしました。