您好,登录后才能下订单哦!
这篇文章将为大家详细讲解有关Swift性能高效的原因有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
自从2014年Apple发布Swift语言以来,历时六年多,Swift已经发布到5.3版本,在5.0版本已经ABI stability,5.2版本也已经module stability,不管是语言还是基础库都日趋稳定,目前国内外大厂也都积极拥抱Swift阵营。
绝大多数公司选择Swift语言开发iOS应用,主要原因是因为Swift相比Objc有更快的运行效率,更加安全的类型检测,更多现代语言的特性提升开发效率;这一系列的优点使Swift语言的热度越来越高。
大多数人知道Swift语言相比于Objc语言运行效率更高,但是却不知道为什么效率更高,在这里我们Swift编译层探讨一下Swift语言高效的原因。
更加高效的数据类型
在开始讨论Swift数据类型之前,我们先讨论一下Swift的函数派发机制;
静态派发、动态派发、消息派发(static dispatch、dynamic dispatch、message dispatch)
动态派发(dynamic dispatch): 动态派发是指编译期无法确定应该调用哪个方法,需要在运行时才能确定方法的调用。
静态派发(static dispatch):是在编译期就能确定的调用方法的派发方式。
除了上面两种方式之外,在Swift里面还会使用Objc的消息派发(message dispatch))机制;Objc采用了运行时采用obj_msgsend进行消息派发,所以Objc的一些动态特性在Swift里面也可以被限制的使用。
静态派发相比于动态派发更快,而且静态派发还会进行内联等一些优化,减少函数的寻址及内存地址的偏移计算等一系列操作,使函数的执行速度更快,性能更高。
数据类型(struct/class)
我们都知道,内存分配可以分为堆区(Heap)和栈区(Stack)。由于栈区内存是连续的,内存的分配和销毁是通过入栈和出栈操作进行的,速度要高于堆区。堆区存储高级数据类型,在数据初始化时,查找没有使用的内存,销毁时再从内存中清除,所以堆区的数据存储不一定是连续的。
类(class)和结构体(struct)在内存分配上是不同的,基本数据类型和结构体默认分配在栈区,而像类这种高级数据类型存储在堆区,且堆区数据存储不是线程安全的,在频繁的数据读写操作时,要进行加锁操作。
我们在swift文档里面能看到对结构的描述,结构体是值类型(Value Type),当值类型的数据赋值给一个变量或常量,或者传递给一个函数时,是值拷贝;
例如:
struct Resolution { var width = 0 var height = 0 } let hd = Resolution(width: 1920, height: 1080) var cinema = hd cinema.width = 2048 print("cinema is now \(cinema.width) pixels wide") // Prints "cinema is now 2048 pixels wide" print("hd is still \(hd.width) pixels wide") // Prints "hd is still 1920 pixels wide"
通过这个例子我们能清楚的看到,当hd赋值给cinema时,是将hd中存储的值拷贝给cinema,所以当给cinema的width属性赋值的时候,并不会改变hd中的属性值,如下图所示:
结构体除了属性的存储更安全、效率更高之外,其函数的派发也更高效。由于结构体不能被继承,也就是结构体的类型被final修饰,根据我们对于动态派发及静态派发的描述,那么其内部函数应该是属于静态派发,在编译期就确定了函数的执行方式,其函数的调用通过内联(inline)的方式进行优化,其内存连续,减少了函数的寻址及内存地址的偏移计算,其运行相比于动态派发更加高效。
协议类型(protocol type)
多态是面向对象的一大特性,在结构体中不能通过继承或者引用语言的多态,swift就引入了协议(protocol),通过协议来实现了结构体的多态特性,这也是swift面向协议编程的核心所在。
对于类(class)来说,每个类都会创建一个虚拟函数表指针,这个指针则指向一个v-table表,也就是虚函数表,表内存储着该类的函数指针数组,拥有继承关系的子类会在虚函数表内通过继承顺序(C++可以实现多继承)去展示虚函数表指针。类里面方法的派发则是根据v-table表里面函数指针来进行派发。
而结构体(struct)没有继承,也就是说结构体并没有v-table表用于函数的派发。为了实现这一特性,在结构体的协议(protocol)的实现里添加了Protocol Witness Table用于管理协议类型的方法派发。
编译过程
上面介绍了一些swift在数据结构上的一些优化,除了数据结构优化之外,swift在编译过程也进行了大量的优化,其中最核心的优化,是在编译过程中引入SIL。
SIL,Swift Intermediate Language,是为了优化swift编译过程而设计的中间语言,主要包含了以下功能:
Clang编译流程
Clang编译过程有以下几个缺点:
由于以上这些缺点,swift语言开发团队在开发过程中进行了一系列的优化,其中最关键的是引入SIL.
swift编译流程
Swift作为一个高级别和安全的语言具有以下特点:
高级别语言
安全语言
swift编译流程:
Swift 源码到IR之间的流程:
Swift 编译过程引入SIL有几个优点:
Swift编译器的流程
Swift编译器作为高级编译器,具有以下严格的传递流程结构。
Swift编译器的流程如下:
关于Swift性能高效的原因有哪些就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
关于Swift性能高效的原因有哪些就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。