2014-09-12 114 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