Swift 4.2 引入了一个新的removeAll {where:} 函数。根据我的阅读,它应该比使用过滤器 {where:} 更有效。我的代码中有几个场景,如下所示:
private func getListOfNullDates(list: [MyObject]) -> [MyObject] {
return list.filter{ $0.date == nil }
.sorted { $0.account?.name < $1.account?.name }
}
Run Code Online (Sandbox Code Playgroud)
但是,我不能将 removeAll{where:} 与参数一起使用,因为它是一个常量。所以我需要像这样重新定义它:
private func getListOfNullDates(list: [MyObject]) -> [MyObject] {
var list = list
list.removeAll { $0.date == nil }
return list.sorted { $0.account?.name < $1.account?.name }
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下使用 removeAll 函数是否仍然更有效?还是坚持使用过滤功能更好?
谢谢你提出这个问题
我在 TIO 上使用此代码对这两个函数进行了基准测试:
let array = Array(0..<10_000_000)
do {
let start = Date()
let filtering = array.filter { $0 % 2 == 0 }
let end = Date()
print(filtering.count, filtering.last!, end.timeIntervalSince(start))
}
do {
let start = Date()
var removing = array
removing.removeAll { $0 % 2 == 0 }
let end = Date()
print(removing.count, removing.last!, end.timeIntervalSince(start))
}
Run Code Online (Sandbox Code Playgroud)
(为了使removing和filtering相同,传递给的闭包removeAll应该是{ $0 % 2 != 0 },但我不想通过使用更快或更慢的比较运算符来给任一片段带来优势。)
事实上,removeAll(where:)当删除元素(我们称之为Pr)的概率为 50% 时,速度会更快!以下是基准测试结果:
filter : 94ms
removeAll : 74ms
Run Code Online (Sandbox Code Playgroud)
Pr 当小于 50%时,情况也是如此。
否则,对于更高的 .过滤速度会更快Pr。
需要记住的一件事是,您的代码list是可变的,这可能会导致意外修改。
就我个人而言,我会选择性能而不是旧习惯,从某种意义上说,这个用例更具可读性,因为意图更清晰。
就地删除的意思是交换数组中的元素,以便将要删除的元素放置在某个枢轴索引之后。要保留的元素是主元元素之前的元素:
var inPlace = array
let p = inPlace.partition { $0 % 2 == 0 }
Run Code Online (Sandbox Code Playgroud)
请记住,这partition(by:)不会保留原始顺序。
这种方法的时钟比removeAll(where:)
| 归档时间: |
|
| 查看次数: |
634 次 |
| 最近记录: |