How to speedup setindex! and getindex?

I have a piece of code where the setindex! and getindex function take a lot of time to execute. Quite simplified, the code looks a bit like this:

using Random


function main()
  A = rand(0:0.1:100000, 200,200)

  for step in 1:100000
    for i in 1:200
        for j in 1:200
          incr = (1 - 0.5) * 0.1
            A[i,j] += incr
        end
    end
  end
end

@profview main()

When I run the above code and profile the time it takes to execute, I get the following result:

Most of the time is spent using the setindex! function. Is there a way to speed this up, or do I have to live with the fact that it will be this slow.

I will try two answers

  • this whole loop looks equivalent to A .+= steps * incr, but I assume this block is just a placeholder for more complex logic?
  • of course all the work is in setindex! — the loop is doing nothing else! so I would answer your question with a question “what else would you expect to see in the profile”
2 Likes

Swap the order of your for loops; you’re not accessing sequential elements but rather skipping from column to column.

A decent rule of thumb is that you want the is and js to appear symmetrically in the order that’s written “closest” to the array, in both the indexing and the for loops. In other words, you currently have the sequence i → j → A → i → j. This should be j → i → A → i → j

You can do even better by putting the step loop as the innermost one, but I’m guessing this is reflective of your real problem.

8 Likes

It’s not obvious which parts of this MWE reflects your real problem, but both for safety and for efficiency, you should use for i in axes(A, 1) etc, or simply eachindex. Then you can avoid bounds checks, which can significantly improve performance.

1 Like