Why is for-in slower than while in swift debugging mode ? If you think, yes It was ran in no optimization.
⬇️Below code, Time is compare of for-in and while in no optimization
49999995000000 for-in -- time = 3.3352
4999999950000000 while -- time = 0.3613
⬇️but, If using optimization for speed
49999995000000 for-in -- time = 0.0037
49999995000000 while -- time = 0.0035
I wonder that "why is for-in slower than while in no optimization? and why are for-in and while so fast in optimization? "
import Foundation
func processTime(_ title: String, blockFunction: () -> ()) {
print()
let startTime = CFAbsoluteTimeGetCurrent()
blockFunction()
let processTime = CFAbsoluteTimeGetCurrent() - startTime
print(title, " -- time = \(String(format : "%.4f",processTime))")
}
processTime("for-in") {
var sum = 0
for i in 0..<10000000 {
sum += i
}
print(sum)
}
processTime("while") {
var sum = 0
var i = 0
while i<10000000 {
sum += i
i += 1
}
print(sum)
}
Seasoned Objective-C developers have numerous tips and tricks that they use to aid the debugging process. However, some of these don’t seem as fruitful or are simply not available in Swift and working in the console can sometimes feel clunky and laborious. For example, you can po a variable from the console but the output is sometimes not ideal.
Check out the docs with help type summary add. Swizzling can be a very useful method of debugging in situations where the code you want to inspect is not reachable because you want to check something on a class that is owned by the frameworks or is too deep down in your own framework, for example.
For example, you can have the debugger stop if a specified variable has a certain value, or to stop only after the third or fourth time. You can also add actions and tell the debugger to automatically continue after evaluating the action.
But swizzling is still possible on pure Swift objects by simply decorating methods with the dynamic modifier. Lastly, the Xcode command line tools come with the Swift REPL, which is a way to interactively test your code, directly from the terminal.
From a Swift perspective, your for
loop actually translates to something like this:
let range = 0..<10000000
var iterator = range.makeIterator()
while let next = iterator.next() {
...
}
Notice that's a lot of calls to next
on the range's iterator, which has its own state that has to be kept track of, and IndexingIterator.next
calls a bunch of protocol methods, dispatching which takes some time too as it has to lookup the witness table. See exactly what calls Iterator.next
is going to make here.
If you are in debug mode, none of that is going to be optimised.
Compare that to your while loop, which is basically set something to 0, compare, do the thing in the loop, add 1 to it, repeat. Clearly this is much simpler to do than calling all those methods.
If you enable optimisations however, the compiler can see that the for loop is doing what the while loop does anyway.
Because I find it interesting, I did a little time profile of a loop such as:
var s = ""
for i in 0...10000000 {
s += "\(i)"
}
80% of the time is spent on next()
, and look at how many things it does! My screenshot can't even contain everything. The string concatenating only takes up about 6% (not in the screenshot).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With