提高 Swift 循环性能

Posted

技术标签:

【中文标题】提高 Swift 循环性能【英文标题】:Improve Swift loop performance 【发布时间】:2021-05-01 13:16:52 【问题描述】:

我正在用 swift 编写一个嵌套循环。

我正在使用范围创建一些简单的循环:

for i in 0..<someCount 
   for j in 0..<someOtherCount 
       //some logic here, or even just keep it empty
   

我的函数在我的程序中被调用了几次。如果您使用多个 someCount 和 someOtherCount,它的最大值约为 2097152 个元素,因此它不是微不足道的,但绝对不会导致性能问题。

我遇到的问题是它在发布版本中运行良好,但调试版本太慢了,令人难以置信。我在这个循环中等待了几分钟,即使我移除了身体,所以它什么也不做。几天前我在分析器(Instruments)中查看了它。我不记得一直占用的确切部分,但我记得它以 .next() 结尾 - 所以它可能是 IteratorProtocol.next() 或其他东西。

我想知道是否有人知道我可以用来减少调试构建开销的任何快捷方式/解决方法/替代语法。也许是一个具有合理性能的替代循环 API?

或者这可能是 swift 的一个已知问题,我目前无能为力,或者只能对 swift 项目提出讨论/错误?

如果我注释掉这些循环,如果我重新添加那些空循环,我的程序需要 55 秒 - 它会跳转到 100 秒。

【问题讨论】:

我从来没有说过我在主线程上运行它,我在后台线程上运行它。无论如何,我不确定这有什么关系。我想我应该更清楚地说明发布版本实际上在循环内部进行了处理,并且该部分代码仍然比没有任何内容的调试版本快。但我想这不是真正的问题。问题是仅仅声明循环会减慢我的程序执行到不可用的水平。现在我切换到“while 循环”,所以我仍然可以开发我的程序(我创建了一个函数来将其转换为 while 循环)。 我正在对数据矩阵进行一些处理。 2m 个元素其实并不算多,如果我用 c 或 Sharp 编写它,它会运行得很快。 @RufusMall Swift 在 C# 中的速度几乎相同,差别不大 @aheze 没错!!感谢您编写一个示例来复制它。 0.24 对于这么小的循环来说是巨大的。我现在有一个工作。希望以后能尽快解决问题! 这取决于你在做什么。请记住,这可能会被多次调用,而您实际上还没有将任何逻辑放入循环中。这种浪费加起来。通过更改我的循环,处理现在需要 9 秒,而不是 45-60 秒。当迭代一个非常重要的功能时。无论如何,感谢您的帮助! 【参考方案1】:

现在我写了一个循环函数,我可以用它来代替(笑)。我在这里留下了一个“for i in...”实现,以防其他人想自己尝试一下。

切换所有循环改进了我对小型数据集的处理管道的处理: 从:45.642573105025804 - 60 秒 To:总是在大约 9 秒内执行。

对于更大的数据集,这显然更具影响力。

func loop(iterations: Int, body: (Int) -> Void) 
    var i = 0
//    for i in 0..<iterations 
//        body(i)
//    
    while i < iterations 
        body(i)
        i += 1
    

TLDR:如果您正在为关键的事情编写嵌套的 for 循环,例如用于 ML 或图像处理/矩阵数学或某些游戏开发,您可能可以通过切换到 while 循环来提高调试构建的性能。

【讨论】:

可能值得向 Apple 提交错误。也许他们可以在这里改进迭代器。 谢谢!超级慢的 for 循环让我发疯。知道 while-loop 解决方法和 RELEASE 构建似乎非常快,我现在做得更好。

以上是关于提高 Swift 循环性能的主要内容,如果未能解决你的问题,请参考以下文章

技术学习-Swift子数组提取性能优化分析

如何提高跟随循环的性能

C# 提高数组查找循环性能

优化 Swift 中的嵌套 for 循环

为啥我的 Apps 脚本删除循环运行如此缓慢?我可以提高性能吗?

Groupby、Split 和 Count 组合(删除循环以提高 pytorch 性能)