Tingkatkan ukuran buffer stdout Python
Apakah ada cara untuk meningkatkan stdoutukuran buffer dari 8182 dengan Python atau menunda flush sampai saya benar-benar menelepon flush?
Hal-hal yang saya coba yang tidak berhasil:
- Saya dapat mengatasi masalah ini di Windows karena saya dapat mengakses buffer secara langsung (misalnya, lihat jawaban saya untuk posting ini ). Tapi ini tidak berhasil untuk Unix.
- Saya dapat meningkatkan ukuran buffer untuk file dengan meneruskan
bufferke konstruktor, namunstdoutsudah dibuat. - Mematikan buffering (
python -u) jelas memperburuk keadaan! - Penggunaan buffer sementara akan menghadapi masalah yang sama -
stdoutdihapus setelah setiap byte ke-8192 disalin dari buffer sementara.
Rasional: Tujuannya di sini adalah untuk mengurangi kedipan konsol. Buffer semuanya, sesuai pertanyaan ini memang berfungsi, misalnya ketika saya mencoba di C atau dengan menggunakan Windows API dengan Python, tetapi batas 8182 di Python tampaknya menyebabkan masalah yang tidak bisa saya singkirkan di Unix.
Jawaban
Anda dapat menggabungkan aliran stdout mentah, tersedia sebagai sys.stdout.buffer, dengan ukuran buffer yang lebih besar dengan io.BufferedWriter, lalu menggabungkan aliran biner yang di-buffer yang dihasilkan sebagai aliran teks yang di-buffer dengan io.TextIOWrapper:
import io
import sys
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))
Berikut adalah demonstrasi tentang efek peningkatan ukuran buffer stdout menjadi 100000 sehingga tidak menyiram dua keluaran cetak sepanjang 10.000 karakter hingga pembilas manual dipanggil:
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()
Demo: https://repl.it/@blhsing/UnkemptGullibleDecompiler
Menemukan jawabannya, sebenarnya sangat sederhana:
my_stdout = open( 1, "w", buffering = 100000 )
1adalahfilenountukstdout.sys.stdout = my_stdoutdapat digunakan untuk membuat perubahan keprinttarget default .- Saya hanya menguji ini di Unix.