# Array of Arrays times Array is type unstable

**URL:** <https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924>\
**Category:** General Usage\
**Created:** [July 29, 2020, 10:25pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924 "2020-07-29T22:25:00Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [July 29, 2020, 10:25pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/1 "2020-07-29T22:25:00Z")

</div>

Hi all, I have a code where I need to perform a element by element multiplication of an Array of Arrays `a` of size X with an Array `b` of size X. Note that the inner arrays of `a` are all the same size. In other words, for every inner array of `a`, multiply element-wise by scalar `b[x]`. Using `@code_warntype` shows me that doing `a .* b` is type unstable within a larger code.

If I instead perform a two-level loop to perform the multiplication, then I don’t get a type unstable problem anymore. I can understand that maybe the compiler gets confused by the first way of writing, but then I cannot help it either because, as far as I know, you cannot pre-define the size of the inner arrays of an Array of Arrays, right?

A simple example to illustrate:

```julia
test1 = Array{Array{Float64,1},1}(undef, 10)
test2 = Array{Float64,1}(undef, 10)
for i = 1:10
    test1[i] = rand(100)
    test2[i] = rand()
end
function first_test(test1, test2)::Array{Array{Float64,1},1}
    return test1 .* test2
end
function second_test(test1, test2)::Array{Array{Float64,1},1}
    result = deepcopy(test1) # Have to deepcopy because there is no way to pre-define size of inner arrays
    for i = 1:10
        for k = 1:100
            result[i][k] = test1[i][k] * test2[i]
        end
    end
    return result
end

@code_warntype first_test(test1, test2)
@code_warntype second_test(test1, test2)

```

Do I have to rely on the two-level loop for these kind of operations? Is there another way to do this?

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [July 29, 2020, 11:56pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/2 "2020-07-29T23:56:50Z")

</div>

looks like this is unavoidable, maybe use a matrix for `test1` instead?

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [July 30, 2020, 1:58am UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/3 "2020-07-30T01:58:13Z")

</div>

In this prototype, the dimensions of the inner arrays are the same, but in the future they could vary. Maybe a Dict would be better suited. Thanks!

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [July 31, 2020, 5:42pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/4 "2020-07-31T17:42:56Z")

</div>

Benchmarking the code provided, the type unstable version appears to be faster. It’s worth also benchmarking in the real context.

```julia
julia> @btime first_test($test1, $test2);
  1.126 μs (13 allocations: 8.97 KiB)

julia> @btime second_test($test1, $test2);
  3.853 μs (13 allocations: 9.27 KiB)

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [July 31, 2020, 6:15pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/5 "2020-07-31T18:15:34Z")

</div>

I’m surprised by the type-instability of the broadcasting operation here, but the performance of broadcasting still seems quite good. FWIW, a list comprehension works in this case as well and is type-stable (although it’s slightly slower):

```julia
julia> function first_test(test1, test2)
           return test1 .* test2
       end
first_test (generic function with 1 method)

julia> function list_comprehension(test1, test2)
           [test1[i] * test2[i] for i in eachindex(test1)]
       end
list_comprehension (generic function with 1 method)

julia> using BenchmarkTools

julia> @btime first_test($test1, $test2);
  580.734 ns (13 allocations: 8.97 KiB)

julia> @btime list_comprehension($test1, $test2);
  604.719 ns (13 allocations: 8.97 KiB)

```

---

<div class="post-metadata">

**Author:** ![cosmia](https://avatars.discourse-cdn.com/v4/letter/c/9de0a6/32.png) [@cosmia](https://discourse.julialang.org/u/cosmia)\
**Post date:** [July 31, 2020, 6:49pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/6 "2020-07-31T18:49:34Z")

</div>

> [@tomerarnon](#):
>
> Benchmarking the code provided, the type unstable version appears to be faster. It’s worth also benchmarking in the real context.

Yeah, I noticed that too, but within the larger function I wrote, the type unstable version is slower, not sure why.

> [@rdeits](#):
>
> I’m surprised by the type-instability of the broadcasting operation here, but the performance of broadcasting still seems quite good.

It is indeed, it wasn’t a huge bottleneck in the original code, I was just curious as to whether there was a better way to do this.

---

<div class="post-metadata">

**Author:** ![photor](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/photor/32/14343_2.png) [@photor](https://discourse.julialang.org/u/photor)\
**Post date:** [July 31, 2020, 8:25pm UTC](https://discourse.julialang.org/t/array-of-arrays-times-array-is-type-unstable/43924/7 "2020-07-31T20:25:14Z")

</div>

```julia
test1 = Array{Array{Float64,1},1}(undef, 10)
test2 = Array{Float64,1}(undef, 10)
for i = 1:10
    test1[i] = rand(100)
    test2[i] = rand()
end
function first_test(test1, test2)::Array{Array{Float64,1},1}
    return test1 .* test2
end
function second_test(test1, test2)::Array{Array{Float64,1},1}
    return [test1[i] * test2[i] for i in eachindex(test1)]
end

```

In my case (Julia 1.3.1 on Windows 8.1), the list comprehension version is slightly faster:

```julia
using BenchmarkTools

@btime first_test($test1, $test2);

821.094 ns (13 allocations: 8.97 KiB)

@btime second_test($test1, $test2);

734.008 ns (13 allocations: 8.97 KiB)

```
