Because it's not true! You were right. Only "bitstype" immutables can be
densely packed.
You can see this by unsafely getting Julia to show you the contents as
other types:
julia> pointer_to_array(Ptr{Float64}(pointer(b)), 4)
4-element Array{Float64,1}:
2.17696e-314
2.17696e-314
2.17795e-314
2.17795e-314
# That's not right, let's try them as UInt64 memory offsets:
julia> pointer_to_array(Ptr{UInt64}(pointer(b)), 2)
2-element Array{UInt64,1}:
0x0000000106a16fb8
0x0000000106a16fd0
# Let's try loading one of those as a pointer to type B:
julia> x = unsafe_pointer_to_objref(Ptr{B}(ans[1]))
B(4.0,5.0)
# And let's change it:
julia> x.x = 8.0
8.0
# That change propagated to b:
julia> b
2-element Array{B,1}:
B(8.0,5.0)
B(5.0,6.0)
On Tuesday, March 3, 2015 at 4:14:37 PM UTC-5, Mauro wrote:
>
> > If you're type has only concrete field then it will be densely packed
> > regardless of wether it's immutable or not.
>
> I see, sorry for the misinformation! So how comes that in below example
> this happens:
>
> julia> reinterpret(Float64,a)
> 4-element Array{Float64,1}:
> 4.0
> 5.0
> 5.0
> 6.0
>
> julia> reinterpret(Float64,b)
> ERROR: cannot reinterpret Array of type B
> in reinterpret at array.jl:77
> in reinterpret at array.jl:62
>
>
> > On Tuesday, 3 March 2015 17:15:20 UTC, Mauro wrote:
> >>
> >> > Mauro, I do not quite understand what you're saying about densely
> packed
> >> > arrays, could you explain a bit more?
> >>
> >> Consider:
> >>
> >> julia> immutable A
> >> x::Float64
> >> y::Float64
> >> end
> >>
> >> julia> type B
> >> x::Float64
> >> y::Float64
> >> end
> >>
> >> julia> a = [A(4,5), A(5,6)]
> >> 2-element Array{A,1}:
> >> A(4.0,5.0)
> >> A(5.0,6.0)
> >>
> >> julia> b = [B(4,5), B(5,6)]
> >> 2-element Array{B,1}:
> >> B(4.0,5.0)
> >> B(5.0,6.0)
> >>
> >> Then in memory `a` is actually identical to:
> >>
> >> [4., 5., 5., 6.]
> >>
> >> (or
> >> [4. 5.; 5. 6.] )
> >>
> >> As Julia knows that the type of `a` is Vector{A}, it knows how to
> >> interpret that junk of memory. Conversely, `b` is a vector of pointers
> >> which point to the two instances of `B`. So, working with b is slower
> >> than an Array{Float64,2} whereas a should be just as fast.
> >>
> >> > Thanks,
> >> > Chris
> >> >
> >> > On Tuesday, March 3, 2015 at 11:41:53 AM UTC-5, Mauro wrote:
> >> >>
> >> >> > I believe if all your type fields are concrete (which they are in
> the
> >> >> case
> >> >> > of Float64), the performance should be the same as using
> >> >> Vector{Float64}.
> >> >> > This is really nice since you get to use code that is much more
> >> >> > understandable like state.x instead of state[1] for no penalty.
> >> >>
> >> >> I think to get densely packed array the type needs to be immutable:
> >> >>
> >> >> immutable StateVec
> >> >> x::Float64
> >> >> y::Float64
> >> >> z::Float64
> >> >> end
> >> >>
> >> >> Otherwise it will be an array of pointers.
> >> >>
> >>
> >>
>
>