NSDateFormatterが遅いらしいというのは聞くので、
2017-05-10 形式にフォーマットする速度を、実際に計測してみました。
- NSDateFormatter (インスタンスをキャッシュしない/する)
- time_t + String(format:)
- time_t + strftime
結果
iPhone6 plus にて。
実機 | Simulator | |
---|---|---|
DateFormatter | 18.274 | 9.317 |
DateFormatter shared instance | 1.455 | 0.592 |
localtime + String(format:) | 1.347 | 4.036 |
localtime + strftime | 0.612 | 6.411 |
Listなど、同じフォーマットをたくさん処理するなら、
とりあえずDateFormatterのインスタンスを共有するようにしとけば良さそう。
iOS7未満もサポートするなら、strftimeを使えばいいんじゃないか。
Simulatorでlocaltime使うと妙に遅い理由は何なんだろう。
コード
swift2.3です
func benchmark(@noescape closure: (NSDate) -> Void) -> NSTimeInterval{
let count = 100_000
let date = NSDate()
let start = date
(0..<count).forEach { _ in
closure(date)
}
return NSDate().timeIntervalSinceDate(start)
}
// DateFormatter
let t1 = benchmark() { (date) in
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
let str = formatter.stringFromDate(date)
}
// DateFormatter shared instance
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
let t2 = benchmark { (date) in
let str = formatter.stringFromDate(date)
}
// localtime + String(format:)
let t3 = benchmark { (date) in
var timeValue = Int(date.timeIntervalSince1970) as time_t
let tmValue = localtime(&timeValue)
let str = String(format: "%04d-%02d-%02d", tmValue.memory.tm_year + 1900, tmValue.memory.tm_mon + 1, tmValue.memory.tm_mday)
}
// localtime + strftime
let t4 = benchmark { (date) in
let bufferSize = 11
let buffer = UnsafeMutablePointer<Int8>.alloc(bufferSize)
var timeValue = Int(date.timeIntervalSince1970) as time_t
let tmValue = localtime(&timeValue)
let len = strftime(buffer, bufferSize, "%Y-%m-%d", tmValue);
let str = NSString(bytes: buffer, length: len, encoding: NSASCIIStringEncoding)
buffer.destroy()
}
print(String(format:"DateFormatter %4.3f seconds", t1))
print(String(format:"DateFormatter shared instance %4.3f seconds", t2))
print(String(format:"localtime + String(format:) %4.3f seconds", t3))
print(String(format:"localtime + strftime %4.3f seconds", t4))
補足
- NSDateFormatterはiOS 7からスレッドセーフ
- en_US_POSIX を設定しているのは、和暦設定時もyyyy表示するため