Swift,任重而道远!
Swift,任重而道远!
发表于2014-12-16 08:35| 8232次阅读| 来源CSDN| 57 条评论| 作者伍昆
【编者按:】在今年的WWDC 2014大会上,苹果公司发布了Swift。Swift语言不仅继承了C语言以及Objective-C的特性,而且还克服了C语言的兼容性问题,对于广大开发者来说是个不错的选择。然而,原文作者Tyrone却并不待见Swift,他在使用Swift的过程中,发现Swift并没有想象中的美好。究竟是什么原因呢?一起来看下:
译文如下:
在进行测试前,我作了如下思考:
- 诚然Swift在对数组进行排序时候获得了与C相媲美的优异表现,但是其它方面呢?
- 可能是出于市场营销的效率,苹果给出的标签是比Objective-C快2.6倍、比Python2.7 快8.4倍,真的吗?
- 它有个优美的名字Swift(雨燕),轻盈迅捷,但我们不能沉迷于表象。
我这里主要以一个Swift项目为基础,进行性能测试。以下是一个相关示例代码:
- import Foundation
- public class User : ModelObject, UpdatableFromJSON {
- public var name: String?
- public var handle: String?
- public required init(data: [String : AnyObject]) {
- super.init(data: data)
- updateWithJSON(data)
- }
- public override func updateWithJSON(data: [String : AnyObject]) {
- super.updateWithJSON(data)
- name <<< data["name"]
- handle <<< data["handle"]
- }
- }
import Foundationpublic class User : ModelObject, UpdatableFromJSON {public var name: String?public var handle: String?public required init(data: [String : AnyObject]) {super.init(data: data)updateWithJSON(data)}public override func updateWithJSON(data: [String : AnyObject]) {super.updateWithJSON(data)name <<< data["name"]handle <<< data["handle"]} }
这是一个用于分析500KB大小JSON数据的示例,完整的示例代码请点击 这里 进行下载,示例处理的问题是在1000个会话中找出用户User对应的会员身份。解析器parser读取JSON后,创建Membership对象并指向关联实例User和Convo ,同时根据convos键值创建(或更新)Convo对象堆。
我利用了XCTest的新特性进行了性能测试。测试代码如下所示:
- func testUserConvosSwiftParsingPerformance() {
- let filePath = NSBundle(forClass: PerformanceTests.self).pathForResource("convos", ofType: "json")
- let jsonData = NSData(contentsOfFile: filePath!)
- var error: NSError?
- let jsonObject = NSJSONSerialization.JSONObjectWithData(jsonData!, options: nil, error: &error)! as [String : AnyObject]
- self.measureBlock() {
- let resp = ChatspryClient.UserConvosResponse(data: jsonObject)
- }
- }
func testUserConvosSwiftParsingPerformance() {let filePath = NSBundle(forClass: PerformanceTests.self).pathForResource("convos", ofType: "json")let jsonData = NSData(contentsOfFile: filePath!)var error: NSError?let jsonObject = NSJSONSerialization.JSONObjectWithData(jsonData!, options: nil, error: &error)! as [String : AnyObject]self.measureBlock() {let resp = ChatspryClient.UserConvosResponse(data: jsonObject)} }
我在编译设置中开启了-O模式,测试的设备是第五代iPod Touch,运行的系统是iOS 8,使用的是与iPhone4S相同的A5双核处理器。随着JSON数据处理量的增加,该设备的响应越来越慢。
测试结果是用时1.42s,多么令人吃惊的龟速。于是,我决定马上创建一个Objective-C版本来进行对比。
- @interface CSUser : CSModelObject
- @property (nonatomic, strong) NSString *name;
- @property (nonatomic, strong) NSString *handle;
- @end
- @implementation CSUser
- - (void) updateWithJSON:(NSDictionary *)json
- {
- [super updateWithJSON: json];
- self.name = json[@"name"];
- self.handle = json[@"handle"];
- }
- @end
@interface CSUser : CSModelObject @property (nonatomic, strong) NSString *name; @property (nonatomic, strong) NSString *handle; @end @implementation CSUser - (void) updateWithJSON:(NSDictionary *)json {[super updateWithJSON: json];self.name = json[@"name"];self.handle = json[@"handle"]; } @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 本身的函数。例如:
- public class CSSwiftUser : CSSwiftModelObject {
- public var name: String?
- public var handle: String?
- public override func updateWithJSON(json: NSDictionary) {
- super.updateWithJSON(json)
- name = json["name"] as String?
- handle = json["handle"] as String?
- }
- }
public class CSSwiftUser : CSSwiftModelObject {public var name: String?public var handle: String?public override func updateWithJSON(json: NSDictionary) {super.updateWithJSON(json)name = json["name"] as String?handle = json["handle"] as String?} }
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示例代码如下:
- class CSUser < CSModelObject
- attr_accessor :name, :handle
- def updateWithJSON(json)
- super
- self.name = json[:name]
- self.handle = json[:handle]
- end
- end
class CSUser < CSModelObjectattr_accessor :name, :handledef updateWithJSON(json)superself.name = json[:name]self.handle = json[:handle]end end
注:RubyMotion中暂时没有任何的优化设置选项。
最后的测试结果是:
可见,RubyMotion比Swift跑得更快。因此,Swift是不是真的如宣传所说的那样身手敏捷,真的见仁见智了。不过对于我来说,如果没有进一步的改进,我决定还是使用Objective-C来编写iOS项目好了。
以下是笔者摘取的部分精彩观点:
来自 DemonicEgg的评论:
“本文做了和我差不多的测试,只是没有使用一些第三方库。我发现当我把全部类型转为使用Swift Array<>和Dictionary<>时,我发现更为惊吓的后果,比Objective-C慢了差不多47倍。”
来自 aeturnum的评论:
“JSON解释速度或许还不算最差的性能指标。只不过面对新语言时,留给开发组用来测试的时间预算会有多少呢?所以稳定的Objective-C还是首选。”
来自 vital_chaos的评论:
“我们不应该抹杀新事物。难道小baby一出生就会驾驶?所有语言都是经过千锤百炼才有今天的成就的。性能权且可以作为一个参考而不是全部。
原文出自:Sudeium
(责编/夏梦竹)
更多精彩内容,敬请关注CSDN研发频道微博,一起来畅聊。
本文为CSDN编译整理,未经允许不得转载,如需转载请联系market#csdn.net(#换成@)
Swift,任重而道远!相关推荐
- Swift与LLVM-Clang原理与示例
Swift与LLVM-Clang原理与示例 LLVM 学习 从 简单汇编基础 到 Swift 不简单的 a + 1 作为iOS开发,程序崩溃犹如家常便饭,秉着没有崩溃也要制造崩溃的原则 每天都吃的很饱 ...
- swift笔记——环境搭建及Hello,Swift!
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/enson16855/article/details/29829601 首先要下载XCode6.仅仅有 ...
- Swift中的问号?和感叹号!
Swift语言使用var定义变量,但和别的语言不同,Swift里不会自动给变量赋初始值,也就是说变量不会有默认值,所以要求使用变量之前必须要对其初始化.如果在使用变量之前不进行初始化就会报错: var ...
- swift java混合,如何在Swift中连接或合并数组?
使用Swift 3,根据您的需求和品味,您可以选择其中一个 five following ways 来连接/合并两个数组 . 1.使用Swift标准库(: :)泛型运算符将两个数组合并为一个新数组 S ...
- swift文件服务器,Swift3一行代码将各种类型文件上传到服务器
由于之前一直在忙项目,很久没有写过一篇像样的文章了,现在手上的项目基本是完成了,正好工作时间偷个懒写两篇文章. 将相机或相册图片上传到服务器 先看看最常见的图片上传,也可以选择跳过,后面有直接的封装方 ...
- Swift中NSRange和Range的转换
最近项目再使用swift重构,遇到Range和NSRange转换的问题,这里记录下: 因为要使用NSRange,所以有了下面这段代码,将String转换为NSString后调用 range(of se ...
- swift中单例的创建及销毁
最近项目重构时使用了oc和swift的混编,遇到了关于单例的创建及销毁,这里记录一下 //创建单例private static var _sharedInstance: ViewController? ...
- swift 加载gif 框架图片
swift 加载gif 框架图片 SwiftGifOrigin 以下代码 轻松搞定 let imgView = UIImageView(frame: CGRect(x: 50, y: 100, wid ...
- Swift 圆环进度条
Swift 圆环进度条 import UICircularProgressRing import UIKit import UICircularProgressRing class ViewContr ...
- swift 数组 filter reduce sort 等方法
数组的常用方法 swift 数组有很多的操作方法,但是用的时候用常常想不起来,就列出来看看 map 和 flatMap 对数组中的元素进行变形操作 filter 主要对数组进行过滤 reduce 主要 ...
最新文章
- xml放在工程的那个路径下_Ubuntu下配置pyrouge
- [原]VS2012编译GLEW 1.11
- ubuntu 16.0.4 opencv 3.4.1 + opencv_contrib 3.4.1 cmake-gui 安装
- 基于HotNet2的扩散传播,竟是“图卷积”的特例
- winscp 服务器拒绝了SFTP连接,但它监听FTP连接。 想要用FTP协议来代替SFTP吗?最好是用加密的。
- 服务器安装什么文件可以获取密码,服务器ssh密码在哪获取
- Material Design基础
- JavaWeb EL表达式, JSTL标签及过滤器综合学习
- Fenzo:来自Netflix基于Java语言的Mesos调度器
- 在VS中生成汇编语言程序(.asm文件)的方法
- ftp传输工具 3款免费的ftp传输工具(ftp客户端定时上传下载新体验)
- 0704第五讲异常处理
- Android Studio校园二手交易市场app
- 特斯拉如何驱动顶级客户体验
- 服务器多系统ssd寿命检测,检测 SSD 剩余寿命 寿终正寝之前还能挽回数据
- 中国五矿集团有限公司采购电子商务平台
- 为泰泽铺路, Intel宣布32nm Atom正式出货 规格详解
- 次世代游戏美术模型的特性和制作流程
- 企业微信接入自研小程序流程
- 北京市普通公路配齐交通诱导屏