Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve IO read performance. #31814

Merged
merged 1 commit into from
Apr 24, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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