Swift,任道而重远!

Posted CSDN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Swift,任道而重远!相关的知识,希望对你有一定的参考价值。

【编者按:】在今年的 WWDC 2014大会上,苹果公司发布了Swift。Swift语言不仅继承了C语言以及Objective-C的特性,而且还克服了C语言的兼容性问题,对于广大开发者来说是个不错的选择。然而,原文作者Tyrone却并不待见Swift,他在使用Swift的过程中,发现Swift并没有想象中的美好。究竟是什么原因呢?一起来看下:


译文如下:


在进行测试前,我作了如下思考:


  • 诚然Swift在对数组进行排序时候获得了与C相媲美的优异表现,但是其它方面呢?

  • 可能是出于市场营销的效率,苹果给出的标签是比Objective-C快2.6倍、比Python2.7 快8.4倍,真的吗?

  • 它有个优美的名字Swift(雨燕),轻盈迅捷,但我们不能沉迷于表象。


我这里主要以一个Swift项目为基础,进行性能测试。以下是一个相关示例代码:


  1. import Foundation

  2. public class User : ModelObject, UpdatableFromJSON {

  3. public var name: String?

  4. public var handle: String?

  5. public required init(data: [String : AnyObject]) {

  6. super.init(data: data)

  7. updateWithJSON(data)

  8. }

  9. public override func updateWithJSON(data: [String : AnyObject]) {

  10. super.updateWithJSON(data)

  11. name <<< data["name"]

  12. handle <<< data["handle"]

  13. }

  14. }


这是一个用于分析500KB大小JSON数据的示例,完整的示例代码请点击 这里 进行下载,示例处理的问题是在1000个会话中找出用户User对应的会员身份。解析器parser读取JSON后,创建Membership对象并指向关联实例User和Convo ,同时根据convos键值创建(或更新)Convo对象堆。


我利用了XCTest的新特性进行了性能测试。测试代码如下所示:


  1. func testUserConvosSwiftParsingPerformance() {

  2. let filePath = NSBundle(forClass: PerformanceTests.self).pathForResource("convos", ofType: "json")

  3. let jsonData = NSData(contentsOfFile: filePath!)

  4. var error: NSError?

  5. let jsonObject = NSJSONSerialization.JSONObjectWithData(jsonData!, options: nil, error: &error)! as [String : AnyObject]

  6. self.measureBlock() {

  7. let resp = ChatspryClient.UserConvosResponse(data: jsonObject)

  8. }

  9. }


我在编译设置中开启了-O模式,测试的设备是第五代iPod Touch,运行的系统是ios 8,使用的是与iPhone4S相同的A5双核处理器。随着JSON数据处理量的增加,该设备的响应越来越慢。


测试结果是用时1.42s,多么令人吃惊的龟速。于是,我决定马上创建一个Objective-C版本来进行对比。


  1. @interface CSUser : CSModelObject

  2. @property (nonatomic, strong) NSString *name;

  3. @property (nonatomic, strong) NSString *handle;

  4. @end

  5. @implementation CSUser

  6. - (void) updateWithJSON:(NSDictionary *)json

  7. {

  8. [super updateWithJSON: json];

  9. self.name = json[@"name"];

  10. self.handle = json[@"handle"];

  11. }

  12. @end


同样地我启用了-Os。令人惊喜的是,这个版本的运行用时仅需0.09s,换而言之,它大约比Swift快了将近15倍,而我在Swift和Object-C都已经开启了LLVM优化器。


我尝试对Swift的反常表现进行简单研究,我暂时还不能确定这究竟是Swift本身的原因还是JSONHelpder引起的。唯一的方法是一行行地比照Objective-C语句和Swift语句,再写另一个Objective-C样式的Swift,然后进行Apples To Apples的测试。这或许不是常规的Swift写法,随处都是NSDictionary引用而不是Swift 本身的函数。例如:


  1. public class CSSwiftUser : CSSwiftModelObject {

  2. public var name: String?

  3. public var handle: String?

  4. public override func updateWithJSON(json: NSDictionary) {

  5. super.updateWithJSON(json)

  6. name = json["name"] as String?

  7. handle = json["handle"] as String?

  8. }

  9. }


Swift在-O下运行时会有segfaults(段错误)的情况,为了公平起见,我把Object-C优化器关闭了,这是关闭后两者的比较:


  • Objective-C:0.06s

  • Objective-C样式的Swift:0.29s


让我较迷惑的是Objective-C在关闭优化器后反而运行得更快,这个先放下,不是这次的重点。由上可见,Objective-C样式的Swift获得了可接受的性能表现,但是如果真的这样做,段错误会不断出现,最后导致性能下降。


出于好奇,最后我还使用了RubyMotion以Ruby语言重写Objective-C测试。RubyMotion支持使用Ruby来编写iOS 和安卓应用,程序最后会被编译为相同的机器码,与Swift和Objective-C过程类似。一直以来,我认为Ruby会比Objective-C慢得多,毕竟这是动态和静态语言的区别。


该Ruby示例代码如下:


  1. class CSUser < CSModelObject

  2. attr_accessor :name, :handle

  3. def updateWithJSON(json)

  4. super

  5. self.name = json[:name]

  6. self.handle = json[:handle]

  7. end

  8. end


注:RubyMotion中暂时没有任何的优化设置选项。


最后的测试结果是:


可见,RubyMotion比Swift跑得更快。因此,Swift是不是真的如宣传所说的那样身手敏捷,真的见仁见智了。不过对于我来说,如果没有进一步的改进,我决定还是使用Objective-C来编写iOS项目好了。


以下是笔者摘取的部分精彩观点:


来自 DemonicEgg的评论:


“本文做了和我差不多的测试,只是没有使用一些第三方库。我发现当我把全部类型转为使用Swift Array<>和Dictionary<>时,我发现更为惊吓的后果,比Objective-C慢了差不多47倍。”


来自 aeturnum的评论:


“JSON解释速度或许还不算最差的性能指标。只不过面对新语言时,留给开发组用来测试的时间预算会有多少呢?所以稳定的Objective-C还是首选。”


来自 vital_chaos的评论:


“我们不应该抹杀新事物。难道小baby一出生就会驾驶?所有语言都是经过千锤百炼才有今天的成就的。性能权且可以作为一个参考而不是全部。


本文为CSDN编译整理,点击“阅读原文”可查看全文并参与讨论。


以上是关于Swift,任道而重远!的主要内容,如果未能解决你的问题,请参考以下文章

swift [Swift Notes]在学习Swift #Swift的同时收集笔记

Swift 反射

Swift入门系列--Swift官方文档(2.2)--中文翻译--About Swift 关于Swift

swift 示例BS swift.swift

swift swift_bug.swift

ios 整理(一)swift和oc的区别