ur3k ur3k - 4 months ago 30
Swift Question

Performance issues while parsing dates

I am having some performance issues in my iOS app while transforming dates that come in a “2013-12-19 00:00:00.000000” format to a medium style date (Dec 25, 2014) and to a double value (epoch). According to the Xcode profiler the two functions that do this process (bellow) are taking approximately 60% of my execution time

I would like to know how to improve this code or if there is a more efficient way to get what I need.

static func getMediumDate(dateString: String) -> (NSString)? {

// Get the: yyyy-MM-dd
let shorDate = dateString[dateString.startIndex..<dateString.startIndex.advancedBy(10)]

let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US")
dateFormatter.dateFormat = "yyyy-MM-dd"

let stringFormatter = NSDateFormatter()
stringFormatter.locale = NSLocale(localeIdentifier: "en_US")
stringFormatter.dateFormat = "yyyy-MM-dd"
stringFormatter.dateStyle = .MediumStyle

let newDate = dateFormatter.dateFromString(shorDate)

if (newDate != nil){
return stringFormatter.stringFromDate(newDate!)
}else{
return nil
}

}



static func getSortDate(dateString:String) -> Double{

// Get the: yyyy-MM-dd
let shorDate = dateString[dateString.startIndex..<dateString.startIndex.advancedBy(10)]

let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US")
dateFormatter.dateFormat = "yyyy-MM-dd"

let newDate = dateFormatter.dateFromString(shorDate)

let value = newDate?.timeIntervalSince1970

if value < DBL_MIN{
return 0
}else if value > DBL_MAX{
return DBL_MAX
}else if value != nil{
return value!
}else{
return 0
}
}

Answer

NSDateFormatter is notoriously slow. You should create it once, cache it and reuse the same instance rather than creating a new instance every time.

For example, you can do the following:

extension NSDateFormatter {
    private static let standardDateFormatter: NSDateFormatter = {
        let dateFormatter = NSDateFormatter()
        dateFormatter.locale = NSLocale(localeIdentifier: "en_US")
        dateFormatter.dateFormat = "yyyy-MM-dd"
        return dateFormatter
    }()
}