# Evaluating the "for" condition

Hello everyone. The following simple example is just to ask the question: will Julia evaluate the length function 5 times? Thank you.

``````function test()
v = [1,2,3,4,5]
for i = 1:length(v)
println(v[i])
end
end
``````

No

1 Like

A quick and no-brainer way to check if performance is affected (while not answering your question exactly):

``````using BenchmarkTools

v = [1:10_000]

function test1(v)
for i = 1:length(v)
println(v[i])
end
end

@btime test1(v)
120.894 ΞΌs (22 allocations: 800 bytes)

function test2(v)
n = length(v)
for i = 1:n
println(v[i])
end
end

@btime test2(v)
121.065 ΞΌs (22 allocations: 800 bytes)

``````
1 Like

The key thing to understand here is that `1:length(v)` is just an ordinary Julia expression that creates a βrangeβ object storing the endpoints. This object gets evaluated once, before the `for` loop starts, and gets re-used on every iteration as needed.

More generally, whenever you do `for x = X` or (equivalently) `for x in X`, for any expression `X`, the expression `X` is evaluated once and then the resulting iterable object is re-used during the loop.

4 Likes

I only knew `@time`, I liked `@btime`, very good!

Thank @lmiq, @ptoche and @stevengj.

2 Likes

I tend to avoid the combination of `@btime` and `println`. How far do you have to scroll back up to compare the results?

In the OPβs code, itβs just something to do inside the loop.

``````julia> length(v)
1
``````

Though your example is still valid perhaps you meant `v=[i for i in 1:10_000]`?

perhaps you meant `v=[i for i in 1:10_000]` ?

I meant something big thatβs all.

You can see it explicitely with:

``````julia> function test()
v = [1,2,3,4,5]
for i = 1:length(v)
println(v[i])
end
end
test (generic function with 1 method)

julia> @code_lowered test()
CodeInfo(
1 β       v = Base.vect(1, 2, 3, 4, 5)
β   %2  = Main.length(v)
β   %3  = 1:%2
β         @_2 = Base.iterate(%3)
β   %5  = @_2 === nothing
β   %6  = Base.not_int(%5)
βββ       goto #4 if not %6
2 β %8  = @_2
β         i = Core.getfield(%8, 1)
β   %10 = Core.getfield(%8, 2)
β   %11 = Base.getindex(v, i)
β         Main.println(%11)
β         @_2 = Base.iterate(%3, %10)
β   %14 = @_2 === nothing
β   %15 = Base.not_int(%14)
βββ       goto #4 if not %15
3 β       goto #2
4 β       return nothing
)
``````