# How to simplify Array type w/o mem alloc

**URL:** <https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 29, 2025, 4:41pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535 "2025-04-29T16:41:57Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bjarthur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjarthur/32/9638_2.png) [@bjarthur](https://discourse.julialang.org/u/bjarthur)\
**Post date:** [April 29, 2025, 4:41pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/1 "2025-04-29T16:41:57Z")

</div>

after `reinterpret`ing and `dropdims`ing on an `Array`, the result is a complicated type which nominally is equivalent to just an Array. i can use `collect` to simplify it, but it allocates memory. is there a way to simplify it without memory allocation? here’s an MWE:

```julia
julia> using FixedPointNumbers, Colors

julia> A = rand(N0f8, 4, 300,500);

julia> @time B = dropdims(reinterpret(RGBA{N0f8}, A), dims=1);
  0.036302 seconds (219.65 k allocations: 11.421 MiB, 99.83% compilation time)

julia> @time B = dropdims(reinterpret(RGBA{N0f8}, A), dims=1);
  0.000008 seconds (2 allocations: 80 bytes)

julia> typeof(B)
Base.ReshapedArray{RGBA{N0f8}, 2, Base.ReinterpretArray{RGBA{N0f8}, 3, UInt8, Array{UInt8, 3}, false}, Tuple{}}

julia> @time C = collect(dropdims(reinterpret(RGBA{N0f8}, A), dims=1)); # only the collect is different here
  0.033743 seconds (114.19 k allocations: 6.190 MiB, 99.52% compilation time)

julia> @time C = collect(dropdims(reinterpret(RGBA{N0f8}, A), dims=1));
  0.000089 seconds (5 allocations: 608.156 KiB)

julia> typeof(C)
Matrix{RGBA{N0f8}} (alias for Array{RGBA{Normed{UInt8, 8}}, 2})

julia> B == C
true

```

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 29, 2025, 6:59pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/2 "2025-04-29T18:59:03Z")

</div>

There’s always `unsafe_wrap`, but as the name indicates, you need to be careful. I _think_ it should be OK if you set it up as follows and make sure no other task has a reference to `A`, but don’t take my word for it.

```julia-repl
julia> GC.@preserve A begin
           @assert size(A, 1) == 4 # sizeof(RGBA{T}) == 4sizeof(T)
           Bptr = convert(Ptr{RGBA{eltype(A)}}, pointer(A))
           B = unsafe_wrap(Array, Bptr, size(A)[2:end])
           # do stuff with B
           # but don't even think about touching A
           # for the remainder of this block
           display(B[1:10, 1:10])
           # finally, discard all unsafe references
           Bptr = nothing
           B = nothing
       end
10×10 Matrix{RGBA{N0f8}}:
 RGBA(0.714, 0.051, 0.325, 0.427) … RGBA(0.055, 0.824, 0.447, 0.961)
 RGBA(0.827, 0.98, 0.8, 0.553) RGBA(0.745, 0.204, 0.125, 0.365)
 RGBA(0.4, 0.49, 0.302, 0.514) RGBA(0.604, 0.824, 0.502, 0.161)
 RGBA(0.89, 0.616, 0.373, 0.604) RGBA(0.573, 0.737, 0.439, 0.314)
 RGBA(0.643, 0.161, 0.165, 0.537) RGBA(0.875, 0.133, 0.2, 0.855)
 RGBA(0.847, 0.922, 0.314, 0.565) … RGBA(0.835, 0.267, 0.675, 0.651)
 RGBA(0.404, 0.039, 0.471, 0.098) RGBA(0.008, 0.714, 0.047, 0.098)
 RGBA(0.922, 0.082, 0.867, 0.576) RGBA(0.918, 0.2, 0.31, 0.047)
 RGBA(0.808, 0.467, 0.529, 0.773) RGBA(0.486, 0.263, 0.757, 0.639)
 RGBA(0.871, 0.216, 0.259, 0.506) RGBA(0.031, 0.745, 0.278, 0.227)

```

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 29, 2025, 7:12pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/3 "2025-04-29T19:12:55Z")

</div>

There’s no safe way to have multiple references with different `eltype` to the same memory, because the compiler assumes that differently typed references never overlap (type-based aliasing analysis). Hence why this can only be achieved through `unsafe_` means, putting the onus on you to stay on the straight and narrow and avoid things that would confuse the compiler or GC.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [April 29, 2025, 7:14pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/4 "2025-04-29T19:14:50Z")

</div>

Why not just use `view`?

```julia
julia> using FixedPointNumbers, Colors

julia> A = rand(N0f8, 4, 300,500);

julia> B = @btime view(reinterpret(RGBA{N0f8}, $A), 1, :, :);
  3.386 ns (0 allocations: 0 bytes)

julia> size(B)
(300, 500)

```

---

<div class="post-metadata">

**Author:** ![danielwe](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/danielwe/32/35657_2.png) [@danielwe](https://discourse.julialang.org/u/danielwe)\
**Post date:** [April 29, 2025, 7:24pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/5 "2025-04-29T19:24:26Z")

</div>

I don’t think `view` addresses the misgivings about having a complicated wrapper type. Allocation-wise it makes no difference; both `dropdims` and `view` are allocation-free when benchmarked properly. That said, `view` is a hair faster (2 ns vs. 5.5 ns on my laptop).

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [April 29, 2025, 7:57pm UTC](https://discourse.julialang.org/t/how-to-simplify-array-type-w-o-mem-alloc/128535/6 "2025-04-29T19:57:37Z")

</div>

It doesn’t solve the wrapping issue, but you can use `reinterpret(reshape, ...)` to handle the dimension dropping:

```julia-repl
julia> reinterpret(reshape, RGBA{N0f8}, A) |> typeof
Base.ReinterpretArray{RGBA{N0f8}, 2, N0f8, Base.ReinterpretArray{N0f8, 3, UInt8, Array{UInt8, 3}, false}, true}

julia> reinterpret(reshape, RGBA{N0f8}, A)
300×500 reinterpret(reshape, RGBA{N0f8}, reinterpret(N0f8, ::Array{UInt8, 3})) with eltype RGBA{N0f8}:
# ...

```
