Swift,任重而道远!

发表于 2014-12-16 08:35| 8232次阅读| 来源 CSDN| 57 条评论| 作者 伍昆

Apple Swift Objective-C 性能测试
摘要:苹果公司对外宣称,性能是Swift带给OS X和iOS开发人员的好处之一。然而,独立开发者Tyrone执行的基准测试显示,与Objective-C相比,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项目为基础,进行性能测试。以下是一个相关示例代码:

[js] view plain copy print ?
  1. importFoundation
  2. publicclassUser:ModelObject,UpdatableFromJSON{
  3. publicvarname:String?
  4. publicvarhandle:String?
  5. publicrequiredinit(data:[String:AnyObject]){
  6. super.init(data:data)
  7. updateWithJSON(data)
  8. }
  9. publicoverridefuncupdateWithJSON(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的新特性进行了性能测试。测试代码如下所示:

[js] view plain copy print ?
  1. functestUserConvosSwiftParsingperformance(){
  2. letfilePath=NSBundle(forClass:PerformanceTests.self).pathForResource("convos",ofType:"json")
  3. letjsonData=NSData(contentsOfFile:filePath!)
  4. varerror:NSError?
  5. letjsonObject=NSJSONSerialization.JSONObjectWithData(jsonData!,options:nil,error:&error)!as[String:AnyObject]
  6. self.measureBlock(){
  7. letresp=ChatspryClient.UserConvosResponse(data:jsonObject)
  8. }
  9. }

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

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

[js] view plain copy print ?
  1. @interfaceCSUser:CSModelObject
  2. @property(nonatomic,strong)Nsstring*name;
  3. @property(nonatomic,strong)Nsstring*handle;
  4. @end
  5. @implementationCSUser
  6. -(void)updateWithJSON:(NSDictionary*)json
  7. {
  8. [superupdateWithJSON: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 本身的函数。例如:

[js] view plain copy print ?
  1. publicclassCSSwiftUser:CSSwiftModelObject{
  2. publicvarname:String?
  3. publicvarhandle:String?
  4. publicoverridefuncupdateWithJSON(json:NSDictionary){
  5. super.updateWithJSON(json)
  6. name=json["name"]asstring?
  7. handle=json["handle"]asstring?
  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示例代码如下:

[js] view plain copy print ?
  1. classCSUser<CSModelObject
  2. attr_accessor:name,:handle
  3. defupdateWithJSON(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的评论:

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

来自 aeturnum的评论:

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

来自 vital_chaos的评论:

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

原文出自:Sudeium

(责编/夏梦竹)

更多精彩内容,敬请关注CSDN研发频道微博,一起来畅聊。

Swift,任重而道远!的更多相关文章

  1. canvas中普通动效与粒子动效的实现代码示例

    canvas用于在网页上绘制图像、动画,可以将其理解为画布,在这个画布上构建想要的效果。本文详细的介绍了粒子特效,和普通动效进行对比,非常具有实用价值,需要的朋友可以参考下

  2. H5混合开发app如何升级的方法

    本篇文章主要介绍了H5混合开发app如何升级的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. canvas学习和滤镜实现代码

    这篇文章主要介绍了canvas学习和滤镜实现代码,利用 canvas,前端人员可以很轻松地、进行图像处理,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. localStorage的过期时间设置的方法详解

    这篇文章主要介绍了localStorage的过期时间设置的方法详解的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. 详解HTML5 data-* 自定义属性

    这篇文章主要介绍了详解HTML5 data-* 自定义属性的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  6. HTML5 WebSocket实现点对点聊天的示例代码

    这篇文章主要介绍了HTML5 WebSocket实现点对点聊天的示例代码的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. HTML5的postMessage的使用手册

    HTML5提出了一个新的用来跨域传值的方法,即postMessage,这篇文章主要介绍了HTML5的postMessage的使用手册的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. 教你使用Canvas处理图片的方法

    本篇文章主要介绍了教你使用Canvas处理图片的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  9. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

  10. ios – 声明NSDictionary并在Swift中添加键值对?

    我一直在尝试使用类类型键和值来声明一个NSDictionary,如下所示:这里,“Category”和“SubCategory”是全局类.我知道我不能将类类型用于关键字段.但是,无论如何,我应该做到这一点.有没有办法做到这一点?如何声明专门的NSDictionary或类似的东西来做到这一点?

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部