Cool. Thanks for clearing this up.
On Tue, 2015-03-03 at 22:25, Matt Bauman <[email protected]> wrote:
> 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.
>> >> >>
>> >>
>> >>
>>
>>