Horribly Slow Objc migrated to fast code

In an application I wrote, I have a process that parses a large amount of data from Core-Data and displays it on a graph. While doing this processing, I am also writing data to a CSV file. I created a separate class called CSVLine that helps with the creation of the CSV file.
For my 140k test case written my Objective-C code takes approximately 12 seconds to run. After "transferring" the class to the fast one, it now takes from 280 to 360 seconds. Obviously I did something terrible.

Using Tools, I was able to identify the "slow" method and I was wondering if I did anything in SWIFT to cause the problem.

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] = @"";
    }
}

      

Swift

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


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

      

I am working with different types of data that are all written to one CSV file, so there are a lot of blank lines. For this, I designed this class to have an array keys

and an array values

. This keys

stores the column names for the CSV file, and the values ​​will store either a space or an index value key

for that data item.

Example:

Keys = [speed, heading, lat, lon]

can be [200,300, "," "]

or ["," "," 38.553 "," 25.2256 "]

Once I'm done with the line, I'll write a comma list of values ​​into the internal data structure and clear the string (remove all elements in the array values

). It seems that this slowdown is happening with the fast-paced class. Is there something blatantly "slow" I do when I zero out my array?

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

}

      

+3


source to share


2 answers


It looks like my problems are caused by the debug build. There is no optimization in the debug build. Once you run it, the optimization will start and everything will run MUCH MUCH faster ....



As in the answer posted here: Is Swift fast when working with numbers?

+2


source


Make sure the Swift optimization level in your build settings is not the only one. In my experience, it is orders of magnitude slower than -O. (-O is also the default for "release", so you can just create for release as suggested.) As far as "zeroing" the array, it might be faster (though I don't know) to initialize the array with a duplicate value:

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

      

Or, if you know that you will add new values ​​as you go and are not required to use indices, you can call:



values.removeAll(keepCapacity: true)

      

And add new values ​​with .append () values, not by indices.

+5


source







All Articles