Strange behavior when passing an Array to a function


#1

Hi all:

I found something strange. In this code, vecadd1 doesn’t change c even if I put the ! before (c,a,b,N). However, vecadd2 will change c even if I remove ! from the function. The two functions do the same, but vecadd1 is a vectorized form, while vecadd2 is a devectorized form. I understand that Arrays are always visible from the caller, so vecadd2 is the right behavior. What is going on with vecadd1?

module VectorizedTest

# vectorized
# CAUTION: This won't change c
function vecadd1(c,a,b,N)
    for i = 1:N
        c = a .+ b;
    end
end

# devectorized: works better than vectorized code
# CAUTION: this will change c
function vecadd2!(c,a,b,N)
    for i = 1:N, j = 1:length(c)
        c[j] = a[j] + b[j]
    end
end

A = rand(2)
B = rand(2)
C = zeros(2)
N = 100000000

println(C)
time1()=@time vecadd1(C,A,B,N)
time1()
println(C)

A = rand(2)
B = rand(2)
C = zeros(2)
N = 100000000

println(C)
time2()=@time vecadd2!(C,A,B,N)
time2()
println(C)


end

#2

You need c .= a .+ b for in-place assignment (or equivalently @. c = a + b). The bang (!) is just a syntactic convention denoting a function that modifies one or more of its arguments–it doesn’t change anything about the function’s behavior. Note that for such small arrays, you’re unlikely to get much (if any) boost from ‘vectorization’, since the arrays are smaller than the normal packed vector size (4 Float64s). Static arrays may be a better choice if speed’s a concern.


#3

The ! is a convention, not syntax. Adding it to a function name has no effect on anything at all, except to act as documentation for people reading your code. This also has nothing to do with arrays in particular, since they’re not passed any differently than any other kind of object. What you’re seeing is the fact that c = a .+ b creates a completely new array which happens to also be named c. Creating that new array has no effect on the array which was passed into the fiction, which is why you don’t observe any change outside the function.

On the other hand, you can do c .= a .+ b, which will essentially do the same thing as your for loop and will actually modify c instead of creating a new array.


#4

Thanks stillyslalom. This is my first day with Julia. I am just trying things and particularly trying some affirmations I’ve seen through different forums like vectorization in Julia doesn’t perform better than devectorization.


#5

Thanks rdeits. This is my first day with Julia. I am planning to convert all my matlab code to Julia and before embarking on that I want to code the right way with Julia. So, I am trying out some things.


#6

Welcome!

One of Julia’s biggest advantages over tools like numpy or Matlab is that you don’t need to write vectorized code to get good performance. In fact, the very fastest code often uses for loops when it’s appropriate for the algorithm being implemented.