# Efficient Broadcasting in Julia: CartesianIndex vs. Reshape

**URL:** <https://discourse.julialang.org/t/efficient-broadcasting-in-julia-cartesianindex-vs-reshape/106929>\
**Category:** New to Julia\
**Tags:** broadcast, reshaping\
**Created:** [November 30, 2023, 6:38am UTC](https://discourse.julialang.org/t/efficient-broadcasting-in-julia-cartesianindex-vs-reshape/106929 "2023-11-30T06:38:40Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![swanchristmas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swanchristmas/32/202550_2.png) [@swanchristmas](https://discourse.julialang.org/u/swanchristmas)\
**Post date:** [November 30, 2023, 6:38am UTC](https://discourse.julialang.org/t/efficient-broadcasting-in-julia-cartesianindex-vs-reshape/106929/1 "2023-11-30T06:38:40Z")

</div>

I came across a [discussion post](https://discourse.julialang.org/t/cumbersome-array-reshaping-for-broadcasting-unlike-numpy/21566/19) on using `[CartesianIndex()]` for singleton insertion in Julia arrays. Intrigued by potential performance differences, I conducted a benchmark comparing it with the `reshape` method.  
Benchmark code:

```julia
(M, N, P, K) = (20, 30, 40, 50)
na = [CartesianIndex()]
A = randn(M, N, P)
B = randn(M, N, K)

@time C = A .* B[:,:,na,:]
@time D = A .* reshape(B,M,N,1,K)

```

Results:

```julia
0.001471 seconds (50 allocations: 9.385 MiB)
0.001449 seconds (8 allocations: 9.156 MiB)

```

The reshape approach seems slightly faster, and I’m seeking insights into the reasons behind this performance difference. Any explanations or thoughts are welcome.

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [November 30, 2023, 8:12am UTC](https://discourse.julialang.org/t/efficient-broadcasting-in-julia-cartesianindex-vs-reshape/106929/2 "2023-11-30T08:12:22Z")

</div>

The difference here is not the `CartesianIndex` but rather that the first variant first creates a new array `B[:,:,na,:]` and then computes, whereas `reshape` uses the existing data.

If you change it to

```julia-repl
julia> @time C = A .* @view B[:,:,na,:];
0.002465 seconds (6 allocations: 9.156 MiB)

```

the runtime and allocations will be similar in both cases.

Of course, you could go further and try to remove the extra allocations by pre-allocating an array and doing `@. C = A * @view B[:,:,na,:]` but that is probably not the aim of this question 😉
