是什么使代码 “Swifty”? —— Fast

Swift的官方网站上的About页面列出了三个关键字:

  • 安全(Safe):为了最大限度地减少开发人员的错误;
  • 迅速(Fast):执行的速度要快;
  • 表现力(Expressive):因为Swift的目标是尽可能清晰易懂。

是什么使代码 “Swifty”? —— Safe 介绍了如何有选择地使用类型系统的各个方面和功能,以使我们的代码更易于理解和使用。
是什么使代码 “Swifty”? —— Expressive 介绍了如何使用表达性命名和API设计传达我们的代码意图

Swifty Code —— Fast

性能之路(The path to performance)

Swift的第二个核心目标,就是要快一些,总的来说,这有点棘手。毕竟,编写高性能代码的主要部分在于测量,微调和再次测量。但是,使我们的代码在性能方面与Swift本身更加一致的一种方法是,充分利用标准库所提供的功能——特别是在处理集合(例如字符串)时。

就像我们在 Swift:字符串解析Swift:集合切片中看过一样,Swift标准库针对性能进行了高度优化,并且使我们能够以高效的方式执行许多常见的集合操作-假设我们使用正确的API。

例如,从字符串中删除一组特定字符的一种常见方法是使用旧的ReplacementOccurences(of:with :)API,该API是Swift的String类型从其表亲Objective-C的NSString继承而来的。在这里,我们使用了对该API的一系列调用,以通过删除一组特殊字符来清理字符串:

let sanitizedString = string
    .replacingOccurrences(of: "@", with: "")
    .replacingOccurrences(of: "#", with: "")
    .replacingOccurrences(of: "<", with: "")
    .replacingOccurrences(of: ">", with: "")

上面的实现的问题是,它将导致我们的字符串进行4次单独的迭代——使用较短的字符串,或者在不经常遇到的代码路径中进行上述操作时,这可能不是问题,但可能会变成当我们需要最大性能时的瓶颈。

值得庆幸的是,Swift通常不需要我们在性能代码和优雅代码之间进行选择,我们要做的就是切换到一种更合适的API,在Set中这个API仅通过我们的字符串一次即可删除其中包含的每个字符。,像这样:

let charactersToRemove: Set<Character> = ["@", "#", "<", ">"]
string.removeAll(where: charactersToRemove.contains)

因此,从性能的角度来看,使我们的代码更“Swifty”,有时我们要做的就是探索标准库在面对给定任务时必须提供的内容,尤其是在集合,机会方面相当高,因为有一个优雅,简单的API,它还为我们提供了出色的性能特征。

文章来自 John SundellWhat makes code “Swifty”?中关于Fast的内容

附几个简单性能优化例子:
  • 在这篇文章也是用到了文中这个方法iOS - DeviceToken 解析来解析Token
  • swift filter会创建全新的数组,且会对所有元素进行操作,例如:
bigArray.filter { someCondition }.count > 0

写成如下形式性能更好:

bigArray.contains { someCondition }

这种做法会比原来快得多,主要因为两个方面:它不会去为了计数而创建一整个全新的数组, 并且一旦找到了第一个匹配的元素,它就将提前退出。一般来说,你只应该在需要所有结果时才去选择使用 filter

  • swift Stringprefix总是从头开始,例如:
extension String {
var allPrefixes1: [Substring] {
return (0...self.count).map(self.prefix) }
}
let hello = "Hello"
hello.allPrefixes1 // ["", "H", "He", "Hel", "Hell", "Hello"]

这段代码看上去简单,但是它非常低效。首先,它会遍历一次字符串,来计算其⻓度,这没什 么大问题。但是,之后 n + 1 次对 prefix 的调用中,每一次都是一个 O(n) 操作,这是因为 prifix总是要从头开始工作,然后在字符串上经过所需要的字符个数。在一个线性复杂度的处 理中运行另一个线性复杂度的操作,意味着算法复杂度将会是 O(n2)。随着字符串⻓度的增⻓, 这个算法所花费的时间将以平方的方式增加。

如果可能的话,一个高效的字符串算法应该只对字符串进行一次遍历,而且它应该操作字符串 的索引,用索引来表示感兴趣的子字符串。这里是相同算法的另一个版本:

extension String {
var allPrefixes2: [Substring] {
return [""] + self.indices.map { index in self[...index] } }
}
let hello = "Hello"
hello.allPrefixes2 // ["", "H", "He", "Hel", "Hell", "Hello"]

上面的代码依然需要迭代一次字符串,以获取索引的集合 indices。不过,一旦这个过程完成, map 中的下标操作就是 O(1) 复杂度的。这使得整个算法的复杂度得以保持在 O(n)。

例子来自《Swift进阶》一书原作者【德】Chris Eidhof(克里斯·安道夫) 【德】Ole Begemann (奥勒·毕格曼) 【德】Airspeed Velocity (空速网站),中文版由王巍译

是什么使代码 “Swifty”? —— Safe 介绍了如何有选择地使用类型系统的各个方面和功能,以使我们的代码更易于理解和使用。
是什么使代码 “Swifty”? —— Expressive 介绍了如何使用表达性命名和API设计传达我们的代码意图

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容