歡迎加入QQ討論群258996829
Swift 頭像
蘋果5袋
5
Swift

Swift語言性能對比

發(fā)布時(shí)間:2014-12-22 22:16  回復(fù):0  查看:3795   最后回復(fù):2014-12-22 22:16  

【編者按:】在今年的 WWDC 2014大會上,蘋果公司發(fā)布了Swift。Swift語言不僅繼承了C語言以及Objective-C的特性,而且還克服了C語言的兼容性問題,對于廣大開發(fā)者來說是個(gè)不錯(cuò)的選擇。然而,原文作者Tyrone卻并不待見Swift,他在使用Swift的過程中,發(fā)現(xiàn)Swift并沒有想象中的美好。究竟是什么原因呢?一起來看下:

譯文如下:

在進(jìn)行測試前,我作了如下思考: 

  • 誠然Swift在對數(shù)組進(jìn)行排序時(shí)候獲得了與C相媲美的優(yōu)異表現(xiàn),但是其它方面呢?
  • 可能是出于市場營銷的效率,蘋果給出的標(biāo)簽是比Objective-C快2.6倍、比Python2.7 快8.4倍,真的嗎?
  • 它有個(gè)優(yōu)美的名字Swift(雨燕),輕盈迅捷,但我們不能沉迷于表象。



我這里主要以一個(gè)Swift項(xiàng)目為基礎(chǔ),進(jìn)行性能測試。以下是一個(gè)相關(guān)示例代碼:

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"]
    }
}


這是一個(gè)用于分析500KB大小JSON數(shù)據(jù)的示例,完整的示例代碼請點(diǎn)擊 這里 進(jìn)行下載,示例處理的問題是在1000個(gè)會話中找出用戶User對應(yīng)的會員身份。解析器parser讀取JSON后,創(chuàng)建Membership對象并指向關(guān)聯(lián)實(shí)例User和Convo ,同時(shí)根據(jù)convos鍵值創(chuàng)建(或更新)Convo對象堆。

我利用了XCTest的新特性進(jìn)行了性能測試。測試代碼如下所示:

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)  
    }  
}  

我在編譯設(shè)置中開啟了-O模式,測試的設(shè)備是第五代iPod Touch,運(yùn)行的系統(tǒng)是iOS 8,使用的是與iPhone4S相同的A5雙核處理器。隨著JSON數(shù)據(jù)處理量的增加,該設(shè)備的響應(yīng)越來越慢。

測試結(jié)果是用時(shí)1.42s,多么令人吃驚的龜速。于是,我決定馬上創(chuàng)建一個(gè)Objective-C版本來進(jìn)行對比。

@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。令人驚喜的是,這個(gè)版本的運(yùn)行用時(shí)僅需0.09s,換而言之,它大約比Swift快了將近15倍,而我在Swift和Object-C都已經(jīng)開啟了LLVM優(yōu)化器。

我嘗試對Swift的反常表現(xiàn)進(jìn)行簡單研究,我暫時(shí)還不能確定這究竟是Swift本身的原因還是JSONHelpder引起的。唯一的方法是一行行地比照Objective-C語句和Swift語句,再寫另一個(gè)Objective-C樣式的Swift,然后進(jìn)行Apples To Apples的測試。這或許不是常規(guī)的Swift寫法,隨處都是NSDictionary引用而不是Swift 本身的函數(shù)。例如:

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下運(yùn)行時(shí)會有segfaults(段錯(cuò)誤)的情況,為了公平起見,我把Object-C優(yōu)化器關(guān)閉了,這是關(guān)閉后兩者的比較:


  • Objective-C:0.06s
  • Objective-C樣式的Swift:0.29s


讓我較迷惑的是Objective-C在關(guān)閉優(yōu)化器后反而運(yùn)行得更快,這個(gè)先放下,不是這次的重點(diǎn)。由上可見,Objective-C樣式的Swift獲得了可接受的性能表現(xiàn),但是如果真的這樣做,段錯(cuò)誤會不斷出現(xiàn),最后導(dǎo)致性能下降。

出于好奇,最后我還使用了RubyMotion以Ruby語言重寫Objective-C測試。RubyMotion支持使用Ruby來編寫iOS 和安卓應(yīng)用,程序最后會被編譯為相同的機(jī)器碼,與Swift和Objective-C過程類似。一直以來,我認(rèn)為Ruby會比Objective-C慢得多,畢竟這是動(dòng)態(tài)和靜態(tài)語言的區(qū)別。

該Ruby示例代碼如下:

class CSUser < CSModelObject
  attr_accessor :name, :handle

  def updateWithJSON(json)
    super
    self.name = json[:name]
    self.handle = json[:handle]
  end
end


注:RubyMotion中暫時(shí)沒有任何的優(yōu)化設(shè)置選項(xiàng)。

最后的測試結(jié)果是:

 

可見,RubyMotion比Swift跑得更快。因此,Swift是不是真的如宣傳所說的那樣身手敏捷,真的見仁見智了。不過對于我來說,如果沒有進(jìn)一步的改進(jìn),我決定還是使用Objective-C來編寫iOS項(xiàng)目好了。

您還未登錄,請先登錄

熱門帖子

最新帖子

?