# Why putting partial array in the function argument and update it actually does not change the array?

**URL:** <https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754>\
**Category:** General Usage\
**Created:** [August 20, 2021, 9:45pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754 "2021-08-20T21:45:57Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 9:45pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/1 "2021-08-20T21:45:57Z")

</div>

A small question.

I put the 1st column of an array in the function argument, and update its first value to 100.0.  
However the array does not really change, why?

```
Z = [1.0 2.0; 3.0 4.0]
function f(theta::Array{Float64,1})
    theta[1] = 100.0
end
f(Z[:,1])
println(Z)

```

Output is  
[1.0 2.0; 3.0 4.0]  
So it is the same as the initial value and does not change at all.

However I expect things like  
[100.0 2.0; 3.0 4.0]

Why the array does not change even when I changed it inside the function f?

I have this problem because, say I have a gigantic array Z, I only need to update part of it. So I use function like f to do the update, by inputting only some parts of the big array.  
But I found it does not change the value of Z at all.

Could anyone explain it a little bit?

Thank you very much in advance!

---

<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:** [August 20, 2021, 9:48pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/2 "2021-08-20T21:48:56Z")

</div>

> [@CRquantum](#):
>
> `Z[:,1]`

This creates a _copy_ of the relevant data, which is why changing it has no effect. You can use:

```julia
@view(Z[:, 1])

```

to get a view of that data instead of a copy. You can learn more about views here: [Arrays · The Julia Language](https://docs.julialang.org/en/v1/base/arrays/#Views-(SubArrays-and-other-view-types))

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 9:53pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/3 "2021-08-20T21:53:11Z")

</div>

Thank you very much indeed! The @ view trick seems great, and it looks like view does not influence performance.

Uhm, just a naïve question, so, even for very huge array Z, do you suggest that just putting the whole Z in the argument of a function even if I just need to update partial of it? Does putting big array in the argument influence performance, it shouldn’t, right?

---

<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:** [August 20, 2021, 10:04pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/4 "2021-08-20T22:04:41Z")

</div>

> [@CRquantum](#):
>
> Does putting big array in the argument influence performance, it shouldn’t, right?

No, arrays are passed by reference, as in Fortran. But in Julia slices copy, thus you copied the array before passing it to the function.

It is perfectly fine to pass views if the function will operate on, or return, a slice of the original array. I would say it is even better because the function does not has to handle the dimensions that are not used.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 10:11pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/5 "2021-08-20T22:11:09Z")

</div>

Thank you very much!

A quick and stupid thing, in the above example, then how to use the view trick, I tried

```
 f(@view(Z[:,1]))

```

It gives me an error. Do I need to add a new method or definition for the theta in the argument of function f?  
Or just do not define anything? Like

```
function f(theta)
    println(theta)
    theta[1] = 100.0
    println(theta)
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:** [August 20, 2021, 10:11pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/6 "2021-08-20T22:11:57Z")

</div>

Use `AbstractVector` (dependind on what the function does, and how you have written it, maybe not using anything is better. Restricting type input is important particularly if the function really does not work with other types, and sometimes for readability, but in Julia it is common to let the functions be as generic as possible).

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 20, 2021, 10:18pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/7 "2021-08-20T22:18:15Z")

</div>

From: [https://github.com/JuliaLang/julia/blob/master/doc/src/manual/functions.md#argument-type-declarations](https://github.com/JuliaLang/julia/blob/master/doc/src/manual/functions.md#argument-type-declarations)

> In general, you should use the most general applicable abstract types for arguments, and **when in doubt, omit the argument types**. You can always add argument-type specifications later if they become necessary, and you don’t sacrifice performance or functionality by omitting them.

> [@CRquantum](#):
>
> ```julia
> Z = [1.0 2.0; 3.0 4.0]
> function f(theta::Array{Float64,1})
> theta[1] = 100.0
> end
> 
> ```

Then

```julia
f(@view(Z[:,1]))

```

causes the following error:

> MethodError: no method matching f(::SubArray{Float64, 1, Matrix{Float64}, Tuple{Base.Slice{Base.OneTo{Int64}}, Int64}, true})  
> Closest candidates are:  
> f(::Vector{Float64}) at …

**When in doubt, omit the argument types:**

```julia
function g!(theta)
    theta[1] = 100.0
end
g!(@view(Z[:,1]))
Z

```

```julia
2×2 Matrix{Float64}:
 100.0 2.0
   3.0 4.0

```

You can always add argument-type specifications later if they become necessary, and you don’t sacrifice performance or functionality by omitting them.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 10:25pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/8 "2021-08-20T22:25:32Z")

</div>

@lmiq @genkuroki  
Thank you all!  
Nice! So, even if I do not specify the type of the argument, it does not sacrifice the performance?  
From what you said and the documents you referred to it looks like so which is cool!  
Uhm, eh, is there some cases the performance may be influenced a little bit if I do not specify type?  
Again, sorry if I am kind of repeating. Just wanted to repeatedly absorb some knowledge from you all.

---

<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:** [August 20, 2021, 10:27pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/9 "2021-08-20T22:27:11Z")

</div>

> [@CRquantum](#):
>
> Uhm, eh, is there some cases the performance may be influenced a little bit if I do not specify type?

Not because of that.

There are situations in which you use type information inside the function, like the size of small static arrays, and in these cases one uses the fact that the size can be statically set to improve performance by guaranteeing that temporary arrays inside the function have the size determined at compile time. That is a common thing.

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 10:33pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/10 "2021-08-20T22:33:57Z")

</div>

Thank you!  
Just a small thing, I just checked,

1. the wrong way which copy the array,  

2. the correct @ view trick,  

I checked several times, but it seems @ view is always several times slower and have more allocations and mem bytes? Am I doing wrong or something?

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 20, 2021, 10:39pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/11 "2021-08-20T22:39:18Z")

</div>

Use BenchmarkTools and `@btime` to get a more useful sense of the true time and GC

---

<div class="post-metadata">

**Author:** ![CRquantum](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/crquantum/32/27824_2.png) [@CRquantum](https://discourse.julialang.org/u/CRquantum)\
**Post date:** [August 20, 2021, 10:45pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/12 "2021-08-20T22:45:50Z")

</div>

Thank you very much!  
Cool! Now the results looks much more reasonable!  
The @ view trick is better.

 ![image](https://global.discourse-cdn.com/julialang/original/3X/f/e/fe59c85f2b7ee1412e124976615beba8e8be5bf3.png)

---

<div class="post-metadata">

**Author:** ![genkuroki](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/genkuroki/32/18030_2.png) [@genkuroki](https://discourse.julialang.org/u/genkuroki)\
**Post date:** [August 20, 2021, 10:47pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/13 "2021-08-20T22:47:10Z")

</div>

> [@CRquantum](#):
>
> Nice! So, even if I do not specify the type of the argument, it does not sacrifice the performance?

Yes. Omitting the argument types of functions does not sacrifice the performance.

Julia beginners tend to get bugs because they carelessly write the argument types of functions.

For example, when someone defines `f(x::Array)` and executes `f(a[:,1])` correctly, he is taught how to optimize using `@view`, and he rewrites it as `f(@view a[:,1])`, then his program will suddenly stop working.

The same can be said for `f(x::String)` and `SubString`.

When in doubt, omit the argument types.

**Additional comment 1:** The definition of `struct` should be written in such a way that the concrete types of the fields are determined, otherwise performance degradation will occur (see [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/#Avoid-fields-with-abstract-type)). However, even in that case, too much restriction on types can cause bugs. When in doubt, you can define `struct` in the following way:

```julia
struct Foo{Ta, Tb, Tc}
    a::Ta
    b::Tb
    c::Tc
end

```

**Additional comment 2:** If you check the compilation process and results with `@code_typed`, `@code_llvm`, `@code_native`, etc., it will be more clear that the omission of argument types does not affect the performance.

Input:

```julia
f(x::Float64) = 2.0x + 1.0
@code_llvm debuginfo=:none f(1.2)

```

Output:

```julia
; Function Attrs: uwtable
define double @julia_f_1273(double %0) #0 {
top:
  %1 = fmul double %0, 2.000000e+00
  %2 = fadd double %1, 1.000000e+00
  ret double %2
}

```

Input:

```julia
g(x) = 2x + 1
@code_llvm debuginfo=:none g(1.2)

```

Output:

```julia
; Function Attrs: uwtable
define double @julia_g_1275(double %0) #0 {
top:
  %1 = fmul double %0, 2.000000e+00
  %2 = fadd double %1, 1.000000e+00
  ret double %2
}

```

The above means that the compilation results for executing `f(1.2)` when `f(x::Float64) = 2.0x` and for executing `g(1.2)` when `g(x) = 2x` are completely the same at the llvm level.

Note also that you don’t even need to write `2.0x + 1.0` because it is a floating point number calculation, `2x + 1` is enough. (See → [Avoid using floats for numeric literals in generic code when possible](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-using-floats-for-numeric-literals-in-generic-code-when-possible))

---

<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:** [August 20, 2021, 11:33pm UTC](https://discourse.julialang.org/t/why-putting-partial-array-in-the-function-argument-and-update-it-actually-does-not-change-the-array/66754/14 "2021-08-20T23:33:12Z")

</div>

Actually these benchmarks are not correct. With views you should not allocate anything there. It becomes more clear what is going on if you put that inside a function:

```julia
julia> function foo(x) # receives either the slice or the view
          x[1] = 1
       end
foo (generic function with 1 method)

julia> function bar1(x)
          foo(x[1:2]) #slice copy
       end
bar1 (generic function with 1 method)

julia> @btime bar1($x) # note the $, benchmarktools requires that
  27.352 ns (1 allocation: 96 bytes)
1

julia> function bar2(x)
          foo(@view(x[1:2])) #view
       end
bar2 (generic function with 1 method)

julia> @btime bar2($x)
  1.690 ns (0 allocations: 0 bytes)
1

```
