เพิ่มขนาดบัฟเฟอร์ stdout ของ Python

Nov 26 2020

มีวิธีเพิ่มstdoutขนาดบัฟเฟอร์จาก8182ใน Python หรือชะลอการล้างจนกว่าฉันจะเรียกจริงflushหรือไม่?

สิ่งที่ฉันลองแล้วไม่ได้ผล:

  • ฉันสามารถแก้ไขปัญหานี้ได้ใน Windows เนื่องจากฉันสามารถเข้าถึงบัฟเฟอร์ได้โดยตรง (เช่นดูคำตอบของโพสต์นี้ ) แต่ใช้ไม่ได้กับ Unix
  • ฉันสามารถเพิ่มขนาดบัฟเฟอร์สำหรับไฟล์ได้โดยส่งผ่านbufferไปยังตัวสร้างอย่างไรก็ตามstdoutได้สร้างไว้แล้ว
  • การปิดบัฟเฟอร์ ( python -u) ทำให้ทุกอย่างแย่ลงอย่างเห็นได้ชัด!
  • การใช้บัฟเฟอร์ชั่วคราวพบปัญหาเดียวกัน - stdoutจะถูกล้างหลังจากทุก ๆ 8192 ไบต์ถูกคัดลอกจากบัฟเฟอร์ชั่วคราว

เหตุผล: จุดมุ่งหมายคือเพื่อลดการกะพริบของคอนโซล การบัฟเฟอร์ทุกอย่างตามคำถามนี้ใช้งานได้จริงเช่นเมื่อฉันลองใน C หรือโดยใช้ Windows API ใน Python แต่ขีด จำกัด 8182 ใน Python ดูเหมือนจะทำให้เกิดปัญหาที่ฉันไม่สามารถแก้ไขได้ใน 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 เพื่อที่จะไม่ล้างเอาต์พุตการพิมพ์ที่มีความยาว 10,000 อักขระสองตัวจนกว่าจะมีการเรียกใช้ manual flush:

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 เท่านั้น