Aumentar el tamaño del búfer de salida estándar de Python
¿Hay alguna manera de aumentar el stdout
tamaño del búfer de 8182 en Python o de retrasar el vaciado hasta que realmente llame flush
?
Cosas que he probado que no funcionan:
- Puedo solucionar este problema en Windows porque puedo acceder al búfer directamente (por ejemplo, vea mi respuesta a esta publicación ). Pero esto no funciona para Unix.
- Puedo aumentar el tamaño del búfer para un archivo pasándolo
buffer
al constructor, sin embargo,stdout
ya está construido. - ¡Desactivar el almacenamiento en búfer (
python -u
) obviamente empeora las cosas! - El uso de un búfer temporal encuentra los mismos problemas:
stdout
se vacía después de que cada 8192o byte se copia del búfer temporal.
Justificación: el objetivo aquí es reducir el parpadeo de la consola. El almacenamiento en búfer de todo, según esta pregunta , funciona, por ejemplo, cuando lo intento en C o usando la API de Windows en Python, pero el límite de 8182 en Python parece estar causando problemas que no puedo solucionar en Unix.
Respuestas
Puede envolver el flujo de salida estándar sin procesar, disponible como sys.stdout.buffer
, con un tamaño de búfer más grande con io.BufferedWriter
, y luego envolver el flujo binario almacenado en búfer resultante como un flujo de texto almacenado en búfer con io.TextIOWrapper
:
import io
import sys
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))
A continuación, se muestra una demostración del efecto de aumentar el tamaño del búfer de la salida estándar a 100000 para que no elimine las dos salidas de impresión de 10000 caracteres hasta que se llame a una descarga manual:
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()
Manifestación: https://repl.it/@blhsing/UnkemptGullibleDecompiler
Encontré la respuesta, en realidad muy simple:
my_stdout = open( 1, "w", buffering = 100000 )
1
es elfileno
parastdout
.sys.stdout = my_stdout
se puede utilizar para realizar el cambio en elprint
destino predeterminado .- Solo lo he probado en Unix.