如何提高你的iOS代码性能?(附例子)

95 阅读1分钟

如何提高你的iOS代码性能,减少对数组的搜索

为你的Swift和Objective-C代码优化速度的一个提示

遍历一个数组的时间复杂度是O(n)。听起来可以接受,对吗?我们可能会忽视它对代码性能的影响,当我们在截止日期前有大量的工作要做时,就不会投入更多的精力去思考一个更好的解决方案。但是,一旦使用这种技能成为一种自然的反应,我们可能不知道我们甚至在代码中写了嵌套的for-loop或嵌套的过滤器,这使得时间复杂度增加到O(n²),我们很有可能在以后遭受性能问题。

试着在非顺序的集合类型中搜索,比如SetDictionary ,而不是Array ,因为在Setdictionary 中搜索的时间复杂度是 O(1),而在Array 中搜索的时间复杂度是 O(n)。

在这篇文章中,我将告诉你如何用Setdictionary 来优化速度。

例子1:集合

在例子1中,有所有会员的数据和铂金会员的ID。我们的目标是通过platinumMemberIDs ,从members ,推导出一个白金会员的数组。

let members: [Member]let platinumMemberIDs:[Int]

在优化之前

filter(_:) 的时间复杂度是O(n),而数组的实例方法contains(_:) 的时间复杂度也是O(n)。

下面的方法是对members 数组进行迭代。在每次迭代中,它在platinumMemberIDs 中搜索,检查platinumMemberIDs 是否包含当前成员的ID。

这种方法的时间复杂度是O(n²)。

var platinumMembers = members.filter {    platinumMemberIDs.contains($0.id)}

优化后

由于platinumMemberIDs 的顺序并不重要,我们可以将这些数据保存在非顺序的集合类型Set 。在Set ,搜索的时间复杂度是O(1)。整体时间复杂度降低到O(n)。

let platinumMemberIDSet = Set(platinumMemberIDs)

例2:词典

在例2中,有两组来自不同渠道的用户,我们想找出他们的交集。只要一个用户的电子邮件与另一组中另一个用户的电子邮件相同,我们就假定他们是同一个用户。

let starUsers: [User]let recentUsers: [User]

优化前

最简单的方法是写嵌套for-loops来找出重复的用户,但时间复杂度将是O(n²),不是很理想。

var duplicatedUsers = [User]()

优化后

为了降低时间复杂度,我们可以简单地从recentUsers 数组中创建一个字典,每个用户的电子邮件为键,用户对象为值。

let recentUserMap = Dictionary(uniqueKeysWithValues: recentUsers.map { ($0.email, $0) })

然后我们在starUsers 数组中进行搜索,但是在每次迭代中,我们不需要迭代recentUsers 数组来找出优化后的重复用户。相反,我们直接从recentUserMap ,访问电子邮件与当前明星用户相同的最近用户的用户对象。时间复杂度降低到O(n)。

let duplicatedUsers = starUsers.filter {  guard let _ = recentUserMap[$0.email] else { return false }  return true}