1

I have a 'for' loop similar to this:

for i in 0...n - 1 {
    // do stuff, n is not changed
}

Back in the day, when I coded in FORTRAN, I was taught that this was a very inefficient way to code large 'for' loops.

Does the Swift compiler recognize the non-changing limit and pre-calculate n - 1?

1
  • 2
    It is quite easy to find out: Replace n by some function n() and check how often the function is called ... Commented Mar 20, 2016 at 9:28

1 Answer 1

2

I think the answer is yes.

1...n - 1 represents a Range object. It is a literal of Range. Therefore, when compilation reaches the loop and sees the literal, it thinks

It seems like that you want to create a new Range<Int> object! Here you go! Hmm... So I guess i is of type Int...

and so on.

This means that n - 1 is evaluated when you create the object. And it stays that way, not evaluating it a second time. This code proves it by not printing only one hello:

var n = 10
for i in 1...n - 1 {
    n = 2
    print("Hello")
}

So yeah.

Note:

  • It's better to use 1..<n instead of 1...n - 1 in this case, they are the same.
  • Apple actually recommends you to use this approach instead of the C-style for loop.
  • The C-style for loop will be removed in Swift 3
Sign up to request clarification or add additional context in comments.

5 Comments

It is better to use 0..<n, but why?
It's my opinion... More swiftier, uses fewer characters, and not unclear. @MartinR
If n == 0 then 0 ... n-1 aborts with a runtime exception, but 0 ..< n doesn't (and executes the loop body zero times).
Some nitpicking: 1...n - 1 is not a literal. It is the result of the ... operator applied to the integer literal 1 and the expression n-1.
Thanks all. I like the <n approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.