Tingkatkan ukuran buffer stdout Python

Nov 26 2020

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, namun stdoutsudah 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

1 blhsing Nov 27 2020 at 05:29

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

1 cz Nov 27 2020 at 16:39

Menemukan jawabannya, sebenarnya sangat sederhana:

my_stdout = open( 1, "w", buffering = 100000 )
  • 1adalah filenountuk stdout.
  • sys.stdout = my_stdoutdapat digunakan untuk membuat perubahan ke printtarget default .
  • Saya hanya menguji ini di Unix.