Skip to content

Commit

Permalink
Improve IO read performance. (#31814)
Browse files Browse the repository at this point in the history
Manually extract out a separate noinline _throw_not_readable function.
Addresses #28481 (comment).
  • Loading branch information
tkoolen authored and fredrikekre committed Apr 24, 2019
1 parent 0c4140b commit 98b34fd
Showing 1 changed file with 11 additions and 6 deletions.
17 changes: 11 additions & 6 deletions base/iobuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,13 @@ show(io::IO, b::GenericIOBuffer) = print(io, "IOBuffer(data=UInt8[...], ",
"ptr=", b.ptr, ", ",
"mark=", b.mark, ")")

@noinline function _throw_not_readable()
# See https://github.com/JuliaLang/julia/issues/29688.
throw(ArgumentError("read failed, IOBuffer is not readable"))
end

function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt)
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
from.readable || _throw_not_readable()
avail = bytesavailable(from)
adv = min(avail, nb)
GC.@preserve from unsafe_copyto!(p, pointer(from.data, from.ptr), adv)
Expand All @@ -168,7 +173,7 @@ function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt)
end

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}})
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
from.readable || _throw_not_readable()
avail = bytesavailable(from)
nb = sizeof(T)
if nb > avail
Expand All @@ -184,7 +189,7 @@ end

function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
require_one_based_indexing(a)
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
from.readable || _throw_not_readable()
if offs+nel-1 > length(a) || offs < 1 || nel < 0
throw(BoundsError())
end
Expand All @@ -200,7 +205,7 @@ function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T
end

@inline function read(from::GenericIOBuffer, ::Type{UInt8})
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
from.readable || _throw_not_readable()
ptr = from.ptr
size = from.size
if ptr > size
Expand All @@ -212,7 +217,7 @@ end
end

function peek(from::GenericIOBuffer)
from.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
from.readable || _throw_not_readable()
if from.ptr > from.size
throw(EOFError())
end
Expand Down Expand Up @@ -506,7 +511,7 @@ end
# copy-free crc32c of IOBuffer:
function _crc32c(io::IOBuffer, nb::Integer, crc::UInt32=0x00000000)
nb < 0 && throw(ArgumentError("number of bytes to checksum must be ≥ 0, got $nb"))
io.readable || throw(ArgumentError("read failed, IOBuffer is not readable"))
io.readable || _throw_not_readable()
n = min(nb, bytesavailable(io))
n == 0 && return crc
crc = GC.@preserve io unsafe_crc32c(pointer(io.data, io.ptr), n, crc)
Expand Down

0 comments on commit 98b34fd

Please sign in to comment.