DateFormatter效能深度優化(譯文)

2021-09-24 07:43:39 字數 3135 閱讀 4289

在用instruments的time profiler工具測試之後,我驚奇地發現大約一半的處理時間用於解析日期,所以我的任務是提高日期解析效能。

每個json物件可能有幾個日期,格式為iso 8601字串。 對於每個物件,使用dateformatter將日期字串轉換為date物件,然後使用core data儲存這些物件。 我正在為每個物件建立乙個新的日期格式轉換方法,類似於以下:

for datestring in lotsofdatestrings 

複製**

你可能不認為建立乙個dateformatter物件會非常昂貴,但是你錯了:建立一次dateformatter並重新使用它會帶來很大的效能提公升。

首先,它到底有多快? 格式化100,000個日期字串的簡單測試發現以下內容:

formatter creation

time

*****

10.88 seconds

once

4.15 seconds

哇 - 這是乙個很大的進步。 不足以完全解決效能問題,但足以說明dateformatter建立成本很高。

我建議使用類似以下方式作為建立任何dateformatter的預設方式。 使用此方法建立的dateformatter都會自動快取以供日後使用,即使對於uitableview單元重用等更複雜的情況也是如此。 要使用它,只需呼叫dateformatter.cached(withformat:「」) - 沒有比這更容易了。

private

var cachedformatters = [string : dateformatter]()

extension

dateformatter

let formatter = dateformatter()

formatter.dateformat = format

cachedformatters[format] = formatter

return formatter

}}複製**

儘管有很大改進,但速度提公升2倍還不夠。經過一番研究,我發現ios 10有乙個新的日期格式化類,iso8601dateformatter......很好!不幸的是ios 9支援是必須的,但是讓我們看看它與普通的舊dateformatter相比如何。

使用100,000個日期字串執行相同的測試出需要4.19秒,這比dateformatter慢一點,但僅僅是。如果你支援ios 10+並且效能不是問題,你應該仍然可以使用這個新類,儘管速度會有輕微降低 - 它可能會更徹底地處理所有可能的iso 8601標準。

對替代日期解析解決方案的更多研究獲得了乙個有趣的函式:strptime()。 它是乙個舊的c函式,用於低階日期解析,完成我們需要的所有格式化說明符。 它可以直接在swift中使用,你可以按如下方式使用它。

func

parse

(datestring: string)

-> date?

strptime(cdatestring, "%y-%m-%dt%h:%m:%s%z", &timecomponents)

return

date(timeintervalsince1970: double(mktime(&timecomponents)))

}複製**

最終的解決方案使用另乙個從sscanf()派生的c函式vsscanf()

vsscanf()速度很快,但我花了一些時間搞清楚如何將其轉換為date而不會影響效能。 讓我們直截了當:

class

iso8601dateparser

) components.year = year.pointee

components.minute = minute.pointee

components.day = day.pointee

components.hour = hour.pointee

components.month = month.pointee

components.second = int(second.pointee)

// work out the timezone offset

if houroffset.pointee < 0

let offset = parsecount <= 6 ? 0 :

houroffset.pointee * 3600 + minuteoffset.pointee * 60

// cache calendars per timezone

// (setting it each date conversion is not performant)

iflet calendar = calendarcache[offset]

var calendar = calendar(identifier: .gregorian)

guard

let timezone = timezone(secondsfromgmt: offset) else

calendar.timezone = timezone

calendarcache[offset] = calendar

return calendar.date(from: components)

}}複製**

這可以在0.67秒內解析100,000個日期字串 - 幾乎比原始方法快20倍,比使用快取dateformatter快6倍。

另外我也看到兩篇dateformatter效能**的文章,可以配合著看

[效能優化]dateformatter輕度優化探索

[效能優化]dateformatter深度優化探索

效能測試 效能測試步驟

針對此次庫內作業效能測試,梳理一下期間的工作流程 梳理已有的介面指令碼,確認需要做效能測試的幾個介面,即使用率高,對效能有要求的幾個主要介面。結合頁面的操作,和確認的介面,梳理具體的業務邏輯 同時,請開發人員部署了測試環境。測試環境的伺服器指標,盡量和生產環境一致。部署的時候,負載均衡等情況也盡量和...

《效能之巔》初識效能

效能是一門令人激動 富於變化的學科同時又充滿挑戰的學科。衡量效能乙個重要指標 延時 系統效能是對於整個系統進行研究,包括了所有的硬體元件和整個軟體棧。通用的軟體棧有哪些呢?包括作業系統 os 核心,資料庫和應用程式層。術語中的 全棧 有時候指的是程式應用環境,包含資料庫,應用程式,和 伺服器。效能通...

PHP效能 序 談效能

這裡不談php的效能和其他語言的效能,這裡討論php自身的效能問題。效能是什麼?通俗的來講,效能,就是在固定的環境下能做的事情的多少。為什麼要效能?1 每乙個軟體或 的環境是相對固定的 2 在相當的一段時間內,在保障增加的使用者數量的同時使得當前環境的軟體或 能夠正常執行 3 為了省錢 php的效能...