快速2D阵列性能

问题描述 投票:0回答:1

我正在创建自己创建的Android应用的iOS版本。它涉及许多二维数组访问和分配,并且在Java上运行非常迅速。但是,当我转换为Swift时,我注意到速度非常慢。在对二维Swift数组进行了一些研究之后,我认为问题可能出在2D数组上,因此我决定创建一个简单的程序并为其计时,以测试2D数组的性能。我比较了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中创建更有效的2D数组?在这种情况下,性能对我来说很重要,因此使用一维数组并进行一些数学运算来建立索引会更好吗?

ios arrays swift multidimensional-array swift5
1个回答
0
投票

如果您确实想坚持使用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]
                        }
                    }
                }
            }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.