From bb64a3dad420d73b7f108645b7208da5685c2596 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Mon, 17 Sep 2018 11:03:43 -0400 Subject: [PATCH] fix #28481, faster reading of primitive types from IOStream and IOBuffer (#29186) (cherry picked from commit c0afddf640bc487d8c627d8a078bc276c86fda5a) --- base/iobuffer.jl | 15 +++++++++++++++ base/iostream.jl | 4 ++++ 2 files changed, 19 insertions(+) diff --git a/base/iobuffer.jl b/base/iobuffer.jl index b3efe5076c1ac7..dec5735d2ed3ba 100644 --- a/base/iobuffer.jl +++ b/base/iobuffer.jl @@ -167,6 +167,21 @@ function unsafe_read(from::GenericIOBuffer, p::Ptr{UInt8}, nb::UInt) nothing 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")) + avail = bytesavailable(from) + nb = sizeof(T) + if nb > avail + throw(EOFError()) + end + GC.@preserve from begin + ptr::Ptr{T} = pointer(from.data, from.ptr) + x = unsafe_load(ptr) + end + from.ptr += nb + return x +end + function read_sub(from::GenericIOBuffer, a::AbstractArray{T}, offs, nel) where T @assert !has_offset_axes(a) from.readable || throw(ArgumentError("read failed, IOBuffer is not readable")) diff --git a/base/iostream.jl b/base/iostream.jl index 8454a1e330175a..0f9ef99b146e11 100644 --- a/base/iostream.jl +++ b/base/iostream.jl @@ -401,6 +401,10 @@ if ENDIAN_BOM == 0x04030201 function read(s::IOStream, T::Union{Type{Int16},Type{UInt16},Type{Int32},Type{UInt32},Type{Int64},Type{UInt64}}) return ccall(:jl_ios_get_nbyte_int, UInt64, (Ptr{Cvoid}, Csize_t), s.ios, sizeof(T)) % T end + +read(s::IOStream, ::Type{Float16}) = reinterpret(Float16, read(s, Int16)) +read(s::IOStream, ::Type{Float32}) = reinterpret(Float32, read(s, Int32)) +read(s::IOStream, ::Type{Float64}) = reinterpret(Float64, read(s, Int64)) end function unsafe_read(s::IOStream, p::Ptr{UInt8}, nb::UInt)