2014-09-12 112 views
3

在我編寫的應用程序中,我有一個從Core-Data分析大量數據並將其顯示到圖形的過程。在完成這個處理的同時,我最終也將數據寫入CSV文件。我創建了一個名爲的CSVLine,它可以幫助創建CSV文件。
對於我記錄的140k測試用例,我的Objective-C代碼需要12秒左右的時間才能運行。在將班級「遷移」到swift之後,現在需要280-360秒之間的時間來運行。很顯然,我做了一件可怕的事情。Terribly Slow將Objc遷移到swift代碼

使用工具我能夠識別「慢」的方法,並且我想知道我是否在SWIFT中做了一些明確的事情來解決問題。

Objc

- (void)newLine { 
// NSLog(@"Appending %@", self.csvString); 

    [outData appendData:[self csvData] ]; 
    [self clear]; 
} 

- (void)clear { 

    // Erase every single value 

    for (NSUInteger i = 0; i < [values count]; i ++) { 
     values[i] = @""; 
    } 
} 

斯威夫特

func newLine() { 
    outData.appendData(csvData()) 
    clear() 
} 


// Clear out the Array 
func clear() { 
    for (var i = 0; i < values.count; i++) { 
     values[i] = "" 
    } 
} 

我與如此有許多空行全部被寫入到一個CSV文件中各類數據的工作。爲了適應這一點,我設計了這個類,使它有一個keys的數組和一個values的數組。 keys存儲CSV文件的「列」名稱,值將存儲該數據元素的索引key的空白或值。

實施例:

密鑰= [速度,航向,LAT,LON]

值可能是[200300, 「」, 「」]

或[ 「」, 「」,」一旦我完成了一行,我將寫入一個逗號加入到內部數據結構列表並清除行(清除values數組中的所有項目)。這似乎是迅速上課放緩的地方。 當我將數組置零時,有沒有公然「緩慢」的操作?

全部斯威夫特類

@objc class CSVLineSwift : NSObject { 

    // Define Arrays 
    var keys: [String] = [String]() 
    var values: [String] = [String]() 

    var outData : NSMutableData = NSMutableData() 

    override init() { 

    } 

    // Singelton Operator - Thread Safe :: http://code.martinrue.com/posts/the-singleton-pattern-in-swift 
    class var instance : CSVLineSwift { 

     // Computed Property 
     struct Static { 
      static var instance : CSVLineSwift? 
      static var token: dispatch_once_t = 0 
      } 

     dispatch_once(&Static.token) { 
      Static.instance = CSVLineSwift(); 
     } 

     return Static.instance! 
    } 

    // Erase existing Data 
    func newFile() { 
     outData = NSMutableData(); 
     outData.appendData(headerData()) 
    } 

    func csvString() -> String { 
     return ",".join(values) 
    } 

    func csvData() -> NSData { 
     let string = csvString() 
     let data = string.dataUsingEncoding(NSUTF8StringEncoding) 
     return data! 
    } 


    func addField(field : String) { 
     keys.append(field) 
     values.append("") 
    } 

    func setValueForKey(value:String, key:String) { 

     if let index = find(keys, key) { 
      values[index] = value 
     } else { 
      print("ERROR -- There was no key: \(key) in the header Array") 
     } 
    } 

    func headerString() -> String { 
     return ",".join(keys) 
    } 

    func headerData() -> NSData { 
     return headerString().dataUsingEncoding(NSUTF8StringEncoding)! 
    } 


    func newLine() { 
     outData.appendData(csvData()) 
     clear() 
    } 


    // Clear out the Array 
    func clear() { 
     for (var i = 0; i < values.count; i++) { 
      values[i] = "" 
     } 
    } 

    func writeToFile(fileName : String) { 
     outData.writeToFile(fileName, atomically: true) 
    } 

} 
+4

您確定您在兩種情況下都使用發佈版本進行測試嗎?使用Swift,調試和發佈版本之間的性能差異可能會很大。 – 2014-09-12 18:49:04

+0

我想我剛剛發現...現在它的運行正常 - 它的優化不是它... – Jeef 2014-09-12 19:07:53

回答

2

看來我的問題是由於調試版本。在調試版本中沒有優化。一旦你運行構建優化踢和的東西跑得快得多....

在此處發佈答案類似:Is Swift really slow at dealing with numbers?

+0

在我的測試案例中,對16,737,732字節的數組進行清零,從2.37秒(無優化)變爲0.0165秒(優化)。這是143倍更快!順便說一句,在同一臺機器上只花費了0.00827秒的C memset,這是另一個2倍的加速。 – wcochran 2017-10-04 19:31:02

5

確保在構建設置斯威夫特的優化水平不-Onone。根據我的經驗,它比-O要慢幾個數量級。 (-O也是'release'的默認值,所以或者你可以按照已經建議的簡單構建版本。)至於'清零'數組,有重複的值初始化數組:

values = [String](count: values.count, repeatedValue: "") 

或者,如果你知道你會追加新的價值觀,你走,而不是綁定到使用索引,你可以撥打:

values.removeAll(keepCapacity: true) 

並用values.append()而不是在索引處添加新值。

+0

謝謝!我會給這兩個鏡頭。構建設置是罪魁禍首。 – Jeef 2014-09-12 19:11:23