# Best practices

I am running a code which is diagonalizing very large matrices, hence I need to reach the best possible performance. when scanning a vector I was using the following syntax

``````for i in 1:length(vec)
``````

which works fine. However, I am recently receiving the following warning

Indexing with indices obtained from `length`, `size` etc is discouraged. Use `eachindex` or `axes` instead.

Is it just a good practice? or the performance is also affected?

It is best practice. I am not sure if it improves performance, but it is conceivable. It will certainly not harm it.

At any rate, it is strongly recommended, and will improve the safety and generality of your code.

3 Likes

thank you

Using `eachindex` ensures that your code can work with arrays that do not necessarily start with index 1. These types of arrays can be created using OffsetArrays.jl.

2 Likes

If youâre diagonalizing large matrices, odds are the diagonalization is the performance critical part, not the way you index into your vectors.

That said, Iâve been taught iteration is better than indexing (they are the same thing for normal arrays, but itâs a good habit):

``````for item in vec
``````

Or, if you need a counter for some reason

``````for (i, item) in enumerate(vec)
``````
3 Likes

Or
`for (i, item) in pairs(vec)`
if you want the indice in the vec with the item

6 Likes

I agree, but, more emphatically: `enumerate` is the wrong function, `pairs` is the right one, but people always forget it.

Edit: Ah, well, @gustaphe did say âcounterâ, which is alright. I just have a knee-jerk reaction to all the uses of `enumerate`.

3 Likes

`eachindex` usually improves performance anyways because it uses cartesian directly.

3 Likes

Yeah, I see it the other way, I normally either need the indices or just the items, if I need something together with the items itâs probably a counter.

(Plus, `pairs` is so obscure a name I didnât dare recommending it without double checking)

Oh, that is very different from my experience. I think itâs probably 80-20 that I need `pairs`.

Yeah, thatâs what I think is a bit sad. Particularly because I very often see `enumerate` being used to get indices in the wild.

I would say (as a mnemotechnic) that `pairs` is for pairs of `(key, value)` , here `(index,value)`, while, clearly, `enumerate` goes from `one` to the `end`, so is for a counter.

By the way, for `enumerate` it is easy to test for the first iteration `( i == 1)`, but how to test with last iteration ? ( does `( i == end)` works? I do not see how it could). Possibly it is no a real worry, because less frequently interesting that test for first iter, but it arises sometime nevertheless.

On the other side with `pairs` you can do `( i == firstindex(v) ) ` and `( i == lastindex(v) )`, even if it is somewhat verbose?

Comment or suggestions welcome.

2 Likes

If `vec` is meant to a traditional (1-indexed) vector, then the âgeneralityâ argument should be weighed against the simplicity/portability of `length()`.

I believe this trade-off is a bit different for package developers and end-users (especially newcomers to Julia).

Not sure I understand. Is `1:length()` more portable?

As for simplicity, `eachindex()` is simpler than `1:length()`, but perhaps less familiar to newcomers. But, once youâve heard of it, you know it.

1 Like

Is `1:length()` more portable?

Well, in the sense that it looks pretty similar to what you would do in some of Juliaâs competitors.

1 Like

Absolutely, but there are plenty of reasonable things `pairs(vec)` could have meant. I donât know what I would have wanted it to be called, I just know that I never feel entire certain what `pairs` does (or more likely what itâs called).

``````i == length(vec) && return
``````
1 Like

Thatâs a feature. Less risk of off-by-one if youâre translating from `eachindex` than from `1:length`.

`eachindex` is fine and even `for (i, item) in enumerate(vec)` is something that most of us can handle (although it isnât pretty).
The real problem starts when dealing with matrices (and more). Things like `for t = 4:T;i =2:N;x[t,i] = x[t-3,i-1];...` are very easy in traditional notation, but become rather involved when you want to handle OffsetArrays (and what not). I believe this might become a serious hurdle in trying to attract new users.

Thanks all for the discussion!

1 Like
``````for c in CartesianIndices(M)
``````

?

btw, `enumerate` doesnât work with OffsetArray because `i` starts at `1`

in this case, perhaps this: