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 )
  • 1filenoですstdout
  • sys.stdout = my_stdoutデフォルトのprintターゲットに変更を加えるために使用できます。
  • 私はこれをUnixでのみテストしました。