-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
write(io, a::AbstractArray) slow for reinterpret arrays #39781
Comments
The output result depends on whether the |
I think this signature could probably just be widened to accept Line 669 in 909c7f3
|
Although there are problems with the current situation... struct UInt32BE
v::UInt32
end
Base.write(io::IO, x::UInt32BE) = write(io, hton(x.v))
function Base.write(io::IO, a::Array{UInt32BE}) # this is type piracy, though
nb = 0
for x in a
nb += write(io, x)
end
nb
end
function hexstring(x)
buf = IOBuffer()
write(buf, x)
bytes2hex(take!(buf))
end julia> hexstring(0x01234567) # little-endian
"67452301"
julia> hexstring(UInt32BE(0x01234567))
"01234567"
julia> hexstring(UInt32BE.([0x01234567, 0x89abcdef]))
"0123456789abcdef"
julia> hexstring(@view UInt32BE.([0x01234567, 0x89abcdef])[1:2]) # not overloaded
"67452301efcdab89"
julia> ra = reinterpret(UInt32BE, [0x01234567, 0x89abcdef])
2-element reinterpret(UInt32BE, ::Vector{UInt32}):
UInt32BE(0x01234567)
UInt32BE(0x89abcdef)
julia> hexstring(ra)
"0123456789abcdef"
julia> function Base.write(s::IO, a::Base.ReinterpretArray)
write(s, parent(a)) # This loses the information of the reinterpreted eltype
end
julia> hexstring(ra) # Ah...
"67452301efcdab89" |
I don't think we can worry about that. There's an informal contract that the raw bits (in native byte order) of a bits type need to be sufficient to describe and recreate it. (And that we don't run on any big-endian systems :) ) |
Oh, that might not have been a good example. I don't mean that endianness is the problem, but that even with a bitstype, there might be cases where the raw bits and the contents you want to write to the I/O object are different. In any case, I am not the one with the specific problem with custom |
That's why I put endianness in parentheses. I'm not sure it's reasonable to expect such overloads to be observed in all cases. Reading/writing blocks of data at once is a crucial optimization, and many people will write code assuming this property of bits types. For example it would be nice to have #14678, and I'd like to remove the behavior of serializing Ptr as NULL (in fact we already have a "bug" that this is not observed inside Arrays). |
Would be nice to have function write(io::IO, ri::ReinterpretArrays)
write(io, ri.parent)
end Maybe with a fallback for array types that don't have write overloaded? |
Unfortunately I don't think this will be sufficient due to the overly narrow definition of Lines 688 to 690 in 5a6c808
julia> isbitstype(RGB{Float64})
true
julia> write(io, RGB{Float64}(1.0))
ERROR: MethodError: no method matching write(::IOStream, ::RGB{Float64})
Closest candidates are:
write(::IO, ::Any) at io.jl:672
write(::IO, ::Any, ::Any...) at io.jl:673
...
Stacktrace:
[1] write(io::IOStream, x::RGB{Float64})
@ Base ./io.jl:672
[2] top-level scope
@ REPL[69]:1 So I'm forced to |
I think it should usually dispatch to: https://github.com/JuliaLang/julia/blob/master/base/io.jl#L706 |
Try: |
Sending a
Base.ReinterpretArray{UInt8, 2, Float64, Matrix{Float64}, false}
towrite(io, a::AbstractArray)
is a lot slower (26x here) than doing acollect
and sending the collected formMatrix{UInt8}
Adding a method to base that
collect
s first would be the easy way, but that might be cheating and break promises for memory usage?The text was updated successfully, but these errors were encountered: