【问题标题】:swift performance issue: local array vs global array快速性能问题:本地数组与全局数组
【发布时间】:2015-01-12 13:26:24
【问题描述】:

我在 swift 中玩数组时发现了一个奇怪的性能问题。

在以下两个演示代码中,我尝试对数组进行随机复制。 这两个代码的唯一区别是数组定义的位置。

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        var array: [Int] = [] /* HERE */
        var n: Int = 10000
        var timer = NSDate()
        for i in 0 ..< n {
            array.append(i)
        }
        println("append \(n) elements \(NSDate().timeIntervalSinceDate(timer))")
        for i in 0 ..< n {
            var p: Int = Int(arc4random_uniform(UInt32(array.count - i))) + i
            array[i] = array[p]
        }
        println("permutation \(array.count) elements \(NSDate().timeIntervalSinceDate(timer))")
    }
}
// append 10000 elements 0.0597179532051086
// permutation 10000 elements 0.108937978744507

但是当我将数组的定义移到函数外(类内)时,发生了一些奇怪的事情。

import UIKit
class ViewController: UIViewController {
    var array: [Int] = [] /* HERE */
    override func viewDidLoad() {
        super.viewDidLoad()

        var n: Int = 10000
        var timer = NSDate()
        for i in 0 ..< n {
            array.append(i)
        }
        println("append \(n) elements \(NSDate().timeIntervalSinceDate(timer))")
        for i in 0 ..< n {
            var p: Int = Int(arc4random_uniform(UInt32(array.count - i))) + i
            array[i] = array[p]
        }
        println("permutation \(array.count) elements \(NSDate().timeIntervalSinceDate(timer))")
    }
}
// append 10000 elements 0.0645599961280823
// permutation 10000 elements 4.61092203855515

我是 swift 的新手。但我想我熟悉其他编程语言,如 C++、Java、Python。这种行为对我来说真的很奇怪。我有什么想念的吗?

非常感谢您的帮助。 :>

顺便说一句,我的 XCode 版本是 6.1 6A1052D,模拟器是 iPad。我使用调试模式来测试我的代码。但即使在 Release 模式下,第二个代码仍然比第一个慢得多。好难过。 ;

【问题讨论】:

  • 我在 Apple 开发者论坛上发布了这个问题。人们告诉我,我应该声明数组使用“final”关键字来改善性能问题(目前这是一个已知的错误,我想 Apple 的工程师稍后会修复它)。更多详情请查看devforums.apple.com/thread/254344

标签: ios arrays performance swift


【解决方案1】:

有趣的是,如果替换,结果会发生巨大变化:

for i in 0 ..< n {
    let p = Int(arc4random_uniform(UInt32(array.count - i))) + i
    array[i] = array[p]
}

for i in 0 ..< n {
    let p = Int(arc4random_uniform(UInt32(array.count - i))) + i
    let tmp = array[p]
    array[i] = tmp
}

【讨论】:

  • 哇,我试过你的代码,它工作!顺便说一句,第一个有什么问题?我无法理解。 :
  • 代码没有任何“错误”,恕我直言。我认为问题在于 Swift 的数组处理。它一定是试图通过在调整数组之前复制数组来处理争用问题,或者类似的奇怪的事情。似乎值得一个错误报告,但让我们看看是否有其他人提出任何有趣的发现......
  • 同意。我想也许我也应该在 Apple 的论坛上发布这个问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 1970-01-01
  • 2017-08-02
  • 2011-09-16
  • 2019-04-21
  • 1970-01-01
  • 2015-11-28
相关资源
最近更新 更多