Aumentar o tamanho do buffer padrão do Python
Existe uma maneira de aumentar o stdout
tamanho do buffer de 8182 em Python ou atrasar a liberação até que eu realmente chame flush
?
Coisas que tentei que não funcionam:
- Eu posso contornar este problema no Windows porque posso acessar o buffer diretamente (por exemplo, veja minha resposta a esta postagem ). Mas isso não funciona para Unix.
- Posso aumentar o tamanho do buffer de um arquivo passando
buffer
para o construtor, masstdout
já está construído. - Desativar o buffer (
python -u
) obviamente torna as coisas piores! - Usar um buffer temporário encontra os mesmos problemas -
stdout
é liberado após cada 8192º byte é copiado do buffer temporário.
Justificativa: O objetivo aqui é reduzir a oscilação do console. Armazenar tudo em buffer, de acordo com essa pergunta, de fato funciona, por exemplo quando tento em C ou usando a API do Windows em Python, mas o limite de 8182 em Python parece estar causando problemas que não consigo contornar no Unix.
Respostas
Você pode agrupar o fluxo stdout bruto, disponível como sys.stdout.buffer
, com um tamanho de buffer maior com io.BufferedWriter
e, em seguida, agrupar o fluxo binário em buffer resultante como um fluxo de texto em buffer com io.TextIOWrapper
:
import io
import sys
sys.stdout = io.TextIOWrapper(io.BufferedWriter(sys.stdout.buffer, new_size))
Aqui está uma demonstração do efeito de aumentar o tamanho do buffer de stdout para 100.000, de modo que não libere as duas saídas de impressão de 10.000 caracteres até que uma descarga manual seja chamada:
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
Encontrei a resposta, na verdade muito simples:
my_stdout = open( 1, "w", buffering = 100000 )
1
é ofileno
parastdout
.sys.stdout = my_stdout
pode ser usado para fazer a alteração noprint
destino padrão .- Eu só testei isso no Unix.