【问题标题】:Swift 2D Array PerformanceSwift 2D 数组性能
【发布时间】:2020-09-20 10:43:24
【问题描述】:

我正在创建我创建的 Android 应用的 iOS 版本。它涉及大量的二维数组访问和赋值,并且在 Java 上运行得非常快。但是,当我转换为 Swift 时,我注意到速度明显放缓。在对二维 Swift 数组进行了一些研究之后,我认为问题可能出在二维数组上,因此我决定创建一个简单的程序并计时来测试二维数组的性能。我比较了 2D 和 1D 数组的执行时间,有很大的不同。下面是我用来测试性能的程序:

import Foundation

var numberOfItems = 1000
var myArray1 = [[Double]](repeating: [Double](repeating: 0.0, count: numberOfItems), count: numberOfItems)
var myArray2 = [[Double]](repeating: [Double](repeating: 0.0, count: numberOfItems), count: numberOfItems)
var myArray3 = [Double](repeating: 0.0, count: numberOfItems * numberOfItems)
var myArray4 = [Double](repeating: 0.0, count: numberOfItems * numberOfItems)

// 2D array assignment
let start1 = CFAbsoluteTimeGetCurrent()
var x = 0.0
for i in 0..<numberOfItems {
    for j in 0..<numberOfItems {
        myArray1[i][j] = x
        x += 1
    }
}
let diff1 = CFAbsoluteTimeGetCurrent() - start1
print(diff1 * 1000)

// 2D array access and assignment
let start2 = CFAbsoluteTimeGetCurrent()
for i in 0..<numberOfItems {
    for j in 0..<numberOfItems {
        myArray2[i][j] = myArray1[i][j]
    }
}
let diff2 = CFAbsoluteTimeGetCurrent() - start2
print(diff2 * 1000)

// 1D array assignment
var y = 0.0
let start3 = CFAbsoluteTimeGetCurrent()
for i in 0..<(numberOfItems * numberOfItems) {
    myArray3[i] = y
    y += 1
}
let diff3 = CFAbsoluteTimeGetCurrent() - start3
print(diff3 * 1000)

// 1D array access and assignment
let start4 = CFAbsoluteTimeGetCurrent()
for i in 0..<(numberOfItems * numberOfItems) {
    myArray4[i] = myArray3[i]
}
let diff4 = CFAbsoluteTimeGetCurrent() - start4
print(diff4 * 1000)

我使用 -Ounchecked 选项在命令行上运行它。我得到了以下输出(以毫秒为单位,有一些变化,但通常非常接近):

6.0759782791137695
24.2689847946167
2.4139881134033203
1.5819072723388672

显然,2D 和 1D 数组实现之间存在相当大的性能差异,尤其是在访问和分配时。

有没有办法在 Swift 中创建更高效​​的二维数组?在这种情况下,性能对我来说很重要,那么使用一维数组并做一些数学索引会更好吗?

【问题讨论】:

标签: ios arrays swift multidimensional-array swift5


【解决方案1】:

如果您真的想坚持使用 2D 数组,那么您可以使用不安全的缓冲区指针来加快访问速度。然而,一维数组仍然会更有效率。试一试。

    // 2D array assignment
    myArray1.withUnsafeMutableBufferPointer { outer1 -> Void in
        for i in 0..<numberOfItems {
            outer1[i].withUnsafeMutableBufferPointer { inner1 -> Void in
                for j in 0..<numberOfItems {
                    inner1[j] = x
                    x += 1
                }
            }
        }
    }

    // 2D array access and assignment
    myArray1.withUnsafeMutableBufferPointer { outer1 -> Void in
        myArray2.withUnsafeMutableBufferPointer { outer2 -> Void in
            for i in 0..<numberOfItems {
                outer1[i].withUnsafeMutableBufferPointer { inner1 -> Void in
                    outer2[i].withUnsafeMutableBufferPointer { inner2 -> Void in
                        for j in 0..<numberOfItems {
                            inner2[j] = inner1[j]
                        }
                    }
                }
            }
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-28
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多