为什么 for-in 比 swift 调试模式下的慢? [英] Why is for-in slower than while in swift debugging mode?

查看:27
本文介绍了为什么 for-in 比 swift 调试模式下的慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么 for-in 比 swift 调试模式下的慢?如果您认为,是的,它是在未优化的情况下运行的.

⬇️下面的代码,时间是for-in和没有优化的比较

49999995000000for-in -- 时间 = 3.3352

4999999950000000而 -- 时间 = 0.3613

⬇️但是,如果使用速度优化

49999995000000for-in -- 时间 = 0.0037

49999995000000而 -- 时间 = 0.0035

我想知道为什么 for-in 比没有优化的时候慢?为什么 for-in 和 while 的优化速度如此之快?"

import Foundationfunc processTime(_ title: String, blockFunction: () -> ()) {打印()让开始时间 = CFAbsoluteTimeGetCurrent()块函数()让 processTime = CFAbsoluteTimeGetCurrent() - startTime打印(标题,--时间=(字符串(格式:%.4f",processTime))")}进程时间(for-in"){总和 = 0对于 i 在 0..<10000000 {总和 += i}打印(总和)}进程时间(同时"){总和 = 0变量 i = 0而 i<10000000 {总和 += i我 += 1}打印(总和)}

解决方案

从 Swift 的角度来看,你的 for 循环实际上转换成这样:

let range = 0..<10000000var iterator = range.makeIterator()而 let next = iterator.next() {...}

注意,在范围迭代器上有很多对 next 的调用,它有自己的状态需要跟踪,而 IndexingIterator.next 调用了一堆协议方法,调度这也需要一些时间,因为它必须查找见证表.看看究竟什么调用 Iterator.next 将使

80% 的时间都花在了 next() 上,看看它做了多少事情!我的屏幕截图甚至无法包含所有内容.字符串连接只占6%左右(截图中没有).

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)
}

解决方案

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).

这篇关于为什么 for-in 比 swift 调试模式下的慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆