ios - Swift 数组访问器比原生数组慢 5 倍——哪些是推荐的?

标签 ios arrays swift metal

我在大数组(图像)上做循环,通过 Instruments 我发现主要瓶颈是 Array.subscript.nativePinningMutableAddressor,所以我做了这个单元测试来比较,

// average: 0.461 seconds (iPhone6 iOS 10.2) ~5.8 times slower than native arrays
func testArrayPerformance() {
    self.measure {
        var array = [Float](repeating: 1, count: 2048 * 2048)
        for i in 0..<array.count {
            array[(i+1)%array.count] = Float(i)
        }
    }
}

// average: 0.079 seconds
func testNativeArrayPerformance() {
    self.measure {
        let count = 2048 * 2048
        let array = UnsafeMutablePointer<Float>.allocate(capacity: count)
        for i in 0..<count {
            array[(i+1)%count] = Float(i)
        }
        array.deallocate(capacity: count)
    }
}

如您所见,原生数组要快得多。有没有其他方法可以更快地访问数组? “不安全”听起来并不“安全”,但在这种情况下你们会怎么做?是否有任何其他类型的数组可以包装原生数组?

更复杂的例子,你可以看这篇文章的评论:Rendering Text in Metal with Signed-Distance Fields 我用 Swift 重新实现了那个例子,原来的实现需要 52 秒才能启动,https://github.com/endavid/VidEngine/tree/textprimitive-fail

切换到原生数组后,我下降到 10 秒,https://github.com/endavid/VidEngine/tree/fontatlas-array-optimization

在 Xcode 8.3.3 上测试。

编辑1: 此测试的时间在调试配置中,但符号距离字段示例的时间在发布配置中。感谢评论中单元测试的微优化(计数、初始化),但在现实世界的示例中这些微优化可以忽略不计,内存缓冲区解决方案在 iOS 上仍然快 5 倍。

编辑2: 以下是带符号距离场示例中最昂贵函数的计时(iPhone6 上的 Instruments session ),

使用 Swift 数组, Using Swift arrays

使用内存缓冲区, Using memory buffers

Edit3:除了性能问题,我在使用 Swift 数组时遇到了严重的内存问题。 NSKeyedArchiver 会耗尽内存并导致应用程序崩溃。我不得不改用字节缓冲区,并将其存储在 NSData 中。引用提交:https://github.com/endavid/VidEngine/commit/6c1822523a2b18759f294def3188755eaaf98b41

所以我想我的问题的答案是:对于大数组的数字数据(例如图像),最好使用内存缓冲区。

最佳答案

简单地缓存 count 将速度从 0.2 秒提高到 0.14 秒,这是基于指针的代码所用时间的两倍。这完全是意料之中的,因为基于数组的代码将所有元素预初始化为 1

基线:

enter image description here

缓存count之后:

enter image description here

关于ios - Swift 数组访问器比原生数组慢 5 倍——哪些是推荐的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45045811/

相关文章:

java - 查找数组中最小值和最大值的有效方法

ios - 如何在 iOS 8 或更早版本上实现 CLLocationManager.requestLocation()?

android - 使用测试移动应用程序以引用其 ID

ios - 如何从 ReactiveCocoa 信号中获取 "old value"?

c - 对二维数组每行的所有最大元素求和

arrays - Perl 打印显示每个元素的前导空格

iphone - UItextView 阿拉伯文本右对齐

ios - 获取 UISwitch 状态 -Xamarin

IOS,滑动删除单元格时从 firebase 数据库中删除数据

ios - 创建随机数的类实例 - Swift