From ea24b5371368047dcaa11ebbcbdf64cd6eee6174 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 2 May 2023 18:28:13 +0800 Subject: [PATCH] Buffer styled printing When printing directly to stdout, there is a non-negligible overhead compared to simply printing to an IOBuffer. Testing indicates 3 allocations per print argument, and benchmarks reveal a ~2x increase in allocations overall and much as a 10x increase in execution time. Thus, it seems worthwhile to use a temporary buffer in all cases. --- base/strings/io.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/base/strings/io.jl b/base/strings/io.jl index 57c1ab1c3dd4e..446d44398128a 100644 --- a/base/strings/io.jl +++ b/base/strings/io.jl @@ -1004,19 +1004,22 @@ end function _ansi_writer(io::IO, s::Union{<:StyledString, SubString{<:StyledString}}, string_writer::Function) if get(io, :color, false)::Bool + buf = IOBuffer() # Avoid the overhead in repeatadly printing to `stdout` + lastface::Face = FACES.current[][:default] for (str, styles) in eachstyle(s) face = getface(styles) link = let idx=findfirst(==(:link) ∘ first, styles) if !isnothing(idx) string(last(styles[idx]))::String end end - !isnothing(link) && write(io, "\e]8;;", link, "\e\\") - termstyle(io, face, lastface) - string_writer(io, str) - !isnothing(link) && write(io, "\e]8;;\e\\") + !isnothing(link) && write(buf, "\e]8;;", link, "\e\\") + termstyle(buf, face, lastface) + string_writer(buf, str) + !isnothing(link) && write(buf, "\e]8;;\e\\") lastface = face end - termstyle(io, getface(), lastface) + termstyle(buf, getface(), lastface) + write(io, take!(buf)) elseif s isa StyledString string_writer(io, s.string) elseif s isa SubString