# Most Efficient Way to Update and Array/Variable?

**URL:** <https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606>\
**Category:** Performance\
**Tags:** question\
**Created:** [December 5, 2021, 11:36am UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606 "2021-12-05T11:36:21Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [December 5, 2021, 11:36am UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/1 "2021-12-05T11:36:21Z")

</div>

Hi all!  
First of all, thanks for reading.  
I am trying to enhance the performance of this function and I wonder if there is a more Julian way to write it in order to make it faster!

I have 4 variables that I update inside a function ray0 and ray 1 and vectors and Time0 and Time1 are variables.

ray0 gets updated and Time0 recomputed in the while loop, and become ray1 and Time1 is computed. Now, the functions that I call output a new array that I am saving with the corresponding name, and then I rewrite ray0 and Time0 before the next iteration.

Is there a better way to do this?  
Thanks for reading!

```julia
"This is a function that follows the Um and Thurber Pseudo Pending Algorithm"
function PBUT(ray0::Array{Float64, 2},f::Float64,P::Float64,F_V::Interpolations.GriddedInterpolation{Float64, 3, Float64, Gridded{Linear}, Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}},F_S::Interpolations.GriddedInterpolation{Float64, 3, Float64, Gridded{Linear}, Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}}})

# First add the central node
ray0=DoublePoints(ray0)
#p=plot(ray0[:,1],ray0[:,3],marker=:circle,yflip=true)
Time0=TravelTime(ray0,F_S);
Time1=copy(Time0);
dT=1;
# Add the necessary nodes & compute Travel Time
while dT>P
ray1=MoveNodes(ray0,f,F_V);
Time1=TravelTime(ray1,F_S);
dT=abs(Time0-Time1);
#plot!(p,ray1[:,1],ray1[:,3],marker=:circle)
#println("Paso1: dT= $dT")
ray0=copy(ray1);
Time0=copy(Time1);
    if dT<=P
        ray0=DoublePoints(ray1);
        Time0=TravelTime(ray0,F_S);
        ray1=MoveNodes(ray0,1.9,F_V);
        Time1=TravelTime(ray1,F_S);
        dT=abs(Time0-Time1);
        #println("Paso2: dT= $dT")
        #plot!(p,ray1[:,1],ray1[:,3],marker=:circle)
        ray0=copy(ray1);
        Time0=copy(Time1);
    end
end
return Time0,ray0
end

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 5, 2021, 1:50pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/2 "2021-12-05T13:50:44Z")

</div>

If the dimensions do not change, use broadcasting:

```julia
ray0 .= ray1

```

but if `ray1` and `Time1` are new arrays which are obtained from the corresponding functions, you should also, to get better performance, make those functions operate inplace.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [December 5, 2021, 2:05pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/3 "2021-12-05T14:05:34Z")

</div>

> [@marianoarnaiz](#):
>
> `dT=1`

`dt` changes repeatedly between `Int64` and `Float64`.  
You can check type stability using [@code\_warntype](https://docs.julialang.org/en/v1/manual/performance-tips/#man-code-warntype).

Ignoring details like constant vector length, but `ray0=DoublePoints(ray0)` could possibly be implemented to work in-place: `DoublePoints!(ray0)`, avoiding allocations.

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [December 5, 2021, 5:07pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/4 "2021-12-05T17:07:18Z")

</div>

Isn’t broadcasting slower than = … I though it was hahaha

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [December 5, 2021, 5:07pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/5 "2021-12-05T17:07:49Z")

</div>

How can I do this in-place implementation inside de function?

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [December 5, 2021, 5:23pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/6 "2021-12-05T17:23:32Z")

</div>

It mutates _in place_ so it is generally faster than copying and then assigning.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [December 5, 2021, 6:22pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/7 "2021-12-05T18:22:37Z")

</div>

> [@marianoarnaiz](#):
>
> Now, the functions that I call output a new array that I am saving with the corresponding name, and then I rewrite ray0 and Time0 before the next iteration.

Would be better to have `MoveNodes` mutate `ray0` in-place if possible (or write to a pre-allocated output array, so that you don’t keep allocating new arrays over and over.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [December 5, 2021, 7:00pm UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/8 "2021-12-05T19:00:36Z")

</div>

> [@marianoarnaiz](#):
>
> How can I do this in-place implementation inside de function?

Depends on your actual function. Can you share a Minimum Working Example?

You could have a look at sort!

```julia
julia> a = [2,3,1];

julia> sort!(a);

julia> a
3-element Vector{Int64}:
 1
 2
 3

julia> @which sort!(a)
sort!(v::AbstractVector; alg, lt, by, rev, order) in Base.Sort at sort.jl:705

```

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [December 6, 2021, 10:53am UTC](https://discourse.julialang.org/t/most-efficient-way-to-update-and-array-variable/72606/9 "2021-12-06T10:53:22Z")

</div>

See a related `f90` code:  
[AmplitudeSourceLocation/raybending.F90 at master · mogiso/AmplitudeSourceLocation (github.com)](https://github.com/mogiso/AmplitudeSourceLocation/blob/master/raybending.F90)  
The `inout` type indicates arrays with in-place operations, without allocations.

Looking at the code, numerical operations could well dominate allocation times.  
The following package can help to answer such questions:  
[KristofferC/TimerOutputs.jl: Formatted output of timed sections in Julia (github.com)](https://github.com/KristofferC/TimerOutputs.jl)
