In an application I've written I have a process that parses a large amount of data from Core-Data and displays it to a graph. While doing this processing I also end up writing the data out to a CSV File. I created a separate class called CSVLine which assists with the creation of the CSV file.
For my test case of 140k recorded my Objective-C code takes aprox 12 seconds to run. After "migrating" the class over to swift It now takes somewhere between 280-360 seconds to run. Obviously I've done something terrible.
Using Instruments I was able to identify the "slow" method and I was wondering if I've done something clear in SWIFT to cause the issue.
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'm working with various types of data that are all being written to a single CSV file so there are many blank lines. To accommodate for this I designed this class so that it has an array of keys
and an array of values
. The keys
store the "column" names for the CSV file and values will store either a blank or a value for the index of the key
for that data element.
Example:
Keys = [speed,heading,lat,lon]
values might be [200,300,"",""]
or ["","","38.553","25.2256"]
Once I'm done with a line i will write a comma joined list of the values into an internal data structure and clear out the line (erase all the items in the values
array). This seems to be where the slowdown is with the swift class. Is there something blatantly "slow" i'm doing when i zero out my array?
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)
}
}