Skip to content

Commit 98b34fd

Browse files
tkoolenfredrikekre
authored andcommitted
Improve IO read performance. (#31814)
Manually extract out a separate noinline _throw_not_readable function. Addresses #28481 (comment).
1 parent 0c4140b commit 98b34fd

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

base/iobuffer.jl

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,13 @@ show(io::IO, b::GenericIOBuffer) = print(io, "IOBuffer(data=UInt8[...], ",
155155
"ptr=", b.ptr, ", ",
156156
"mark=", b.mark, ")")
157157

158+
@noinline function _throw_not_readable()
159+
# See https://github.com/JuliaLang/julia/issues/29688.
160+
throw(ArgumentError("read failed, IOBuffer is not readable"))
161+
end
162+
158163
function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt)
159-
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
164+
from.readable || _throw_not_readable()
160165
avail = bytesavailable(from)
161166
adv = min(avail, nb)
162167
GC.@preserve from unsafe_copyto!(p, pointer(from.data, from.ptr), adv)
@@ -168,7 +173,7 @@ function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt)
168173
end
169174

170175
function read(from::GenericIOBuffer, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64},Type{Int128},Type{UInt128},Type{Float16},Type{Float32},Type{Float64}})
171-
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
176+
from.readable || _throw_not_readable()
172177
avail = bytesavailable(from)
173178
nb = sizeof(T)
174179
if nb > avail
@@ -184,7 +189,7 @@ end
184189

185190
function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
186191
require_one_based_indexing(a)
187-
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
192+
from.readable || _throw_not_readable()
188193
if offs+nel-1 > length(a) || offs < 1 || nel < 0
189194
throw(BoundsError())
190195
end
@@ -200,7 +205,7 @@ function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
200205
end
201206

202207
@inline function read(from::GenericIOBuffer, ::Type{UInt8})
203-
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
208+
from.readable || _throw_not_readable()
204209
ptr = from.ptr
205210
size = from.size
206211
if ptr > size
@@ -212,7 +217,7 @@ end
212217
end
213218

214219
function peek(from::GenericIOBuffer)
215-
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
220+
from.readable || _throw_not_readable()
216221
if from.ptr > from.size
217222
throw(EOFError())
218223
end
@@ -506,7 +511,7 @@ end
506511
# copy-free crc32c of IOBuffer:
507512
function _crc32c(io::IOBuffer, nb::Integer, crc::UInt32=0x00000000)
508513
nb < 0 && throw(ArgumentError("number of bytes to checksum must be ≥ 0, got $nb"))
509-
io.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
514+
io.readable || _throw_not_readable()
510515
n = min(nb, bytesavailable(io))
511516
n == 0 && return crc
512517
crc = GC.@preserve io unsafe_crc32c(pointer(io.data, io.ptr), n, crc)

0 commit comments

Comments
 (0)