Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
    }
}
like image 860
ur3k Avatar asked Jul 25 '16 18:07

ur3k


2 Answers

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
    }()
}
like image 172
dzl Avatar answered Oct 29 '22 23:10

dzl


Creating NSDateFormatter instance - is a complex CPU consuming task.
It is better to use it once or create shared instance.

Take a look at this thread describing best NSDateFormatter practices - Whats the best practice for NSDateFormatter in Swift?

Also more info on this you can find in Data Formatting Guide from Apple:

Cache Formatters for Efficiency

Creating a date formatter is not a cheap operation. If you are likely to use a formatter frequently, it is typically more efficient to cache a single instance than to create and dispose of multiple instances. One approach is to use a static variable.

So, to refactor your code - you should replace initialisation of 3 NSDataFormatter instances with function that inits and returns only 1 shared instance (1 memory address), then use returned instance.

like image 45
Evgeny Karkan Avatar answered Oct 29 '22 22:10

Evgeny Karkan