# Fast lookup into (almost) constant array

**URL:** <https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085>\
**Category:** General Usage\
**Created:** [May 23, 2018, 12:36am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085 "2018-05-23T00:36:19Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [May 23, 2018, 12:36am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/1 "2018-05-23T00:36:19Z")

</div>

I have this (simplified) code in a module.

```julia
const A = @SMatrix [1.0 2.0;
                    3.0 4.0]

f(r, x::Number) = x * Vector{Float64}(A[r,:])

```

`f` is a bottleneck function. This is already really quick and I’m happy with performance but wondering if I can do better. The multiplier `x` is pretty much a constant, defined on initialisation but also updated occasionally based on user interaction.

Is there a way to gain some more speed by pre-multiplying `A` by `x` and indexing into that array? I haven’t been able to work out a way to do it. The pre-calculation would be done from a different file in the same module, which seems to complicate things.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 23, 2018, 12:49am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/2 "2018-05-23T00:49:43Z")

</div>

The issue is that you are creating a vector which is heap allocated. You’re getting two allocations, the second because of the resulting `*`. It’s faster to just use the resulting `SVector` from indexing the `SMatrix`.

---

<div class="post-metadata">

**Author:** ![Keno](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/keno/32/285_2.png) [@Keno](https://discourse.julialang.org/u/Keno)\
**Post date:** [May 23, 2018, 1:04am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/3 "2018-05-23T01:04:28Z")

</div>

> [@Adriel](#):
>
> Is there a way to gain some more speed by pre-multiplying `A` by `x` and indexing into that array

It’s doubtful that you’d get any speed improvement. A multiply is basically free with a copy, which you’re probably gonna have to do anyway. Depends a bit on the surrounding code though. As @ChrisRackauckas said though, your biggest bottleneck in the above code will be the Vector allocation.

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [May 23, 2018, 1:34am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/4 "2018-05-23T01:34:57Z")

</div>

OK good to know, thanks.

I was definitely allocating needlessly.

```julia
f(r, x::Number) = x * Vector{Float64}(cellcentres[r,:])
f2(r, x::Number) = Vector{Float64}(x * cellcentres[r,:])
f3(r, x::Number) = [(x*cellcentres[r,:]).data...]

```

```julia
julia> @btime f(2, 1000.0);
  46.041 ns (2 allocations: 192 bytes)

julia> @btime f2(2, 1000.0);
  21.496 ns (1 allocation: 96 bytes)

julia> @btime f3(2, 1000.0);
  32.493 ns (3 allocations: 128 bytes)

```

So `f2` is the way to go. It would be nice to get this performance:

```julia
julia> f4(r, x::Number) = x * cellcentres[r,:];

julia> @btime f4(2, 1000.0);
  6.942 ns (0 allocations: 0 bytes)

```

but unfortunately I do need a vector. Thanks again.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [May 23, 2018, 4:16am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/5 "2018-05-23T04:16:12Z")

</div>

> [@Adriel](#):
>
> but unfortunately I do need a vector. Thanks again.

Why? No codes should rely on the underlying data structure, just the actions. If you just allow `AbstractVector` most codes should work just fine, unless you’re modifying this vector in the future, in which case you can just use `setindex`.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [May 23, 2018, 7:38am UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/6 "2018-05-23T07:38:57Z")

</div>

> [@Adriel](#):
>
> but unfortunately I do need a vector.

Yeah, this assumption should definitely be questioned. You can also use an `MVector` if you need mutation.

---

<div class="post-metadata">

**Author:** ![Adriel](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@Adriel](https://discourse.julialang.org/u/Adriel)\
**Post date:** [May 23, 2018, 9:19pm UTC](https://discourse.julialang.org/t/fast-lookup-into-almost-constant-array/11085/7 "2018-05-23T21:19:25Z")

</div>

You’re right of course! I was over-restricting types in the downstream functions. This was a great lesson.
