JuliaIO / BufferedStreams.jl

Fast composable IO streams
MIT License
42 stars 20 forks source link

UX for flushing buffer #81

Open jariji opened 11 months ago

jariji commented 11 months ago

I like to use BufferedStreams for printing to stdout because it's much faster. However, if I forget to flush the buffer, then not all the result get printed to stdout.

using Random, BufferedStreams
let ss = [randstring(20) for _ in 1:10^5]
    @time foreach(println, ss) # 5.463939 seconds (708.34 k allocations: 16.149 MiB)
end

# Incomplete result
let ss = [randstring(20) for _ in 1:10^5]
    io = BufferedOutputStream(stdout)
    @time foreach(ss) do s
        println(io, s)
    end # 0.554888 seconds (2.63 k allocations: 180.951 KiB, 2.34% compilation time)
    # BUT it's incomplete
end;

let ss = [randstring(20) for _ in 1:10^5]
    io = BufferedOutputStream(stdout)
    @time begin
        foreach(ss) do s
            println(io, s)
        end
        flush(io)
    end # 0.547968 seconds (2.64 k allocations: 181.054 KiB, 2.37% compilation time)
end;

What is a good solution to forgetting to flush the buffer?

One approach would be a do block that introduces the buffer at the beginning and flushes it at the end.

function buffering(f, out)
    io = BufferedOutputStream(out)
    try
        f(io)
    finally
        flush(io)
    end
end

let ss = [randstring(20) for _ in 1:10^5]
    @time buffering(stdout) do io
        foreach(ss) do s
            println(io, s)
        end
    end # 0.586527 seconds (8.66 k allocations: 712.136 KiB, 3.35% compilation time)
end;