非常缓慢地将Objc迁移到快速代码

时间:2014-09-12 18:47:14

标签: ios objective-c swift

在我编写的应用程序中,我有一个从Core-Data解析大量数据并将其显示在图表中的流程。在进行此处理时,我最终还是将数据写入CSV文件。我创建了一个名为 CSVLine 的单独类,它可以帮助创建CSV文件 对于140k记录的测试用例,我的Objective-C代码需要大约12秒才能运行。在"迁移"上课到swift它现在需要280-360秒才能运行。显然,我做了一些可怕的事情。

使用仪器,我能够确定"慢"方法和我想知道我是否已经在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存储&#34;列&#34; CSV文件和值的名称将存储空白或该数据元素的key索引的值。

示例:

Keys = [speed,heading,lat,lon]

值可能是[200,300,&#34;&#34;,&#34;&#34;]

或[&#34;&#34;,&#34;&#34;,&#34; 38.553&#34;,&#34; 25.2256&#34;]

一旦我完成一行,我会将一个逗号加入的值列表写入内部数据结构并清除该行(擦除values数组中的所有项目)。这似乎是减速与快速阶级的关系。 有什么明显的&#34;缓慢&#34;当我把阵列归零时,我正在做什么?

Full Swift Class

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

}

2 个答案:

答案 0 :(得分:5)

确保Swift在Build Settings中的优化级别不是-Onone。根据我的经验,它比-O慢几个数量级。 (-O也是'release'的默认值,所以或者你可以简单地构建for release,就像已经建议的那样。)至于'清零'数组,它可能更快(虽然我不知道)简单地重新使用重复值初始化数组:

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

或者,如果您知道随后将追加新值,并且不必使用索引,则可以调用:

values.removeAll(keepCapacity: true)

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

答案 1 :(得分:2)

看来我的问题是由于调试版本所致。在调试版本中没有优化。一旦你进行了一次运行,你就可以开始进行优化,并且运行得更快......

与此处发布的答案类似:Is Swift really slow at dealing with numbers?