Julia code optimization: vector calculation and taking sum

Viewed 119

I'm in a Julia project and I want to optimize my function oneAttempt in my code below.

A brief explanation of my code below:

  • function oneAttmept implements a certain recursive algorithm return the terminal result.
  • A variable f is the variable which is updated through the algorithm which I wrote as algorithm part in the code below(I would omit this part for this question) .
  • function oneAttempt would be called many times (more than 1000 times) under for loop.
function oneAttempt()
            n = 30
            m = 900

            x = rand(Normal(), n, n)
            A = ones(n, n) * sum(sum(x, dims = 1))
    
            # f would be passed to the algorithm below.
            # f0 is the initial value of f
            f0 = ones(n, n) + x - (1 / m) * A
            f = copy(f0)
            o = zeros(n, n)

            #=
            algorithm part:    
            while loop in which f would be updated many times under complicated algorithm 
            =#
            
            return f;
end

# the function `oneAttempt` would be called many times (more than 1000 times) under for loop.

I guess there are better optimized ways of making f0, since I heard vector calculation would be an ordinary bottleneck in Julia coding.

Is there better ways of coding?

Any information would be appreciated.

1 Answers

Your example is not quite self-contained, which makes it harder to suggest improvements, since I don't know which parts I can change without altering its functionality. But in general, I would say that your problem is that you are creating a lot of unnecessary arrays, and your first strategy should be to cut down on that.

For example:

A = ones(n, n) * sum(sum(x, dims = 1))

This creates a vector inside the inner sum, and then sums that. Also, there is no need for the ones(n, n) it's just more allocations with no purpose. Instead, write

A = sum(x)

This sums the entire array x, and no need for an array. (I suspect you are coming from Matlab, where sum(x) sums the columns of a matrix (unless it's a 1xN matrix, in which case it sums the row!), but even in Matlab you can write sum(x, [], 'all') instead of sum(sum(x)).)

Here:

f0 = ones(n, n) + x - (1 / m) * A

you should also avoid unnecessary allocations. No need to create an array, just use broadcasting instead. I would write it like this:

f0 = (1 + A/m) .+ x  # 1 and A/m are both scalar, so don't dot the plus in the parens.

Here

f = copy(f0)
o = zeros(n, n)

you create more arrays, with a copy and zeros. I don't know what they are for, but I suspect you don't need it. If you add more context, I could comment on it.

But in general, cut down on needless arrays, use broadcasting instead, and possibly in-place operations.

Related