编写高性能 Swift - 有效使用容器类型的三点建议
????????关注后回复 “进群” ,拉你进程序员交流群????????
Swift 标准库提供的一个重要功能是通用容器 Array 和 Dictionary。本文将说明如何高效地使用这些类型。
建议:在数组中使用值类型
在 Swift 中,类型可以分为两个不同的类别:值类型(结构,枚举,元组)和引用类型(类)。它们的一个关键区别是,值类型不能包含在 NSArray 中。因此,当使用值类型时,优化器可以消除 Array 中大部分的开销,这些开销对于处理将数组支持 NSArray 的可能性是必需的。
此外,与引用类型相反,值类型仅在递归包含引用类型时才需要引用计数。通过使用没有引用类型的值类型,可以避免额外的保留,释放 Array 内部的空间。
// Don't use a class here.
struct PhonebookEntry {
var name: String
var number: [Int]
}
var a: [PhonebookEntry]
请记住,在使用大的值类型和使用引用类型之间需要权衡。在某些情况下,复制和移动大的值类型的开销将超过消除桥接和保留/释放开销的成本。
建议:当不需要 NSArray 桥接时,将 ContiguousArray 与引用类型一起使用
如果您需要引用类型的数组,并且该数组不需要桥接到 NSArray 时,请使用 ContiguousArray 而不是 Array:
class C { ... }
var a: ContiguousArray<C> = [C(...), C(...), ..., C(...)]
建议:使用适当的突变代替对象重新分配
Swift 中的所有标准库容器都是值类型,使用 COW(写时复制)来执行拷贝,而不是显式拷贝。在许多情况下,这允许编译器通过保留容器而不是执行深拷贝来排除不必要的拷贝。仅当容器的引用计数大于 1 并且容器发生突变时,才通过复制基础容器来完成此操作。例如,在下面的示例中,将 c
分配给 d
时不会发生拷贝,但是当 d
通过添加 2
进行结构突变时,将拷贝 d
,然后将 2
添加到 d
:
var c: [Int] = [ ... ]
var d = c // No copy will occur here.
d.append(2) // A copy *does* occur here.
如果用户不小心,有时 COW 可能会引入其他意外副本。这方面的一个示例是尝试通过函数中的对象重新分配执行变异。在 Swift 中,所有参数都以 +1 传递,即参数保留在调用点之前,然后在被调用者的末尾释放。这意味着如果编写如下函数:
func append_one(_ a: [Int]) -> [Int] {
var a = a
a.append(1)
return a
}
var a = [1, 2, 3]
a = append_one(a)
由于赋值的原因,a 可能是一个拷贝,尽管 a 在 append_one 之后没有使用。可以通过使用 inout
参数来避免这种情况:
func append_one_in_place(a: inout [Int]) {
a.append(1)
}
var a = [1, 2, 3]
append_one_in_place(&a)
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
点击????卡片,关注后回复【面试题
】即可获取
在看点这里好文分享给更多人↓↓
原文地址: https://blog.csdn.net/olsQ93038o99S/article/details/115364400
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章