{"id":40125,"date":"2023-07-21T16:13:51","date_gmt":"2023-07-21T20:13:51","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=40125"},"modified":"2023-07-21T16:13:51","modified_gmt":"2023-07-21T20:13:51","slug":"a-fast-timestamp-parser-in-swift","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2023\/07\/21\/a-fast-timestamp-parser-in-swift\/","title":{"rendered":"A Fast Timestamp Parser in Swift"},"content":{"rendered":"<p><a href=\"https:\/\/juripakaste.fi\/parse3339\/\">Juri Pakaste<\/a> (<a href=\"https:\/\/mastodon.social\/@juri\/110688451279829140\">Mastodon<\/a>):<\/p>\n<blockquote cite=\"https:\/\/juripakaste.fi\/parse3339\/\"><p>It&rsquo;s well known that <code>DateFormatter<\/code>, the main timestamp formatter and parser Apple ships in Foundation, is not particularly fast. It&rsquo;s flexible and it&rsquo;s correct, but it takes its time. The newer <code>ISO8601DateFormatter<\/code> has similar performance.<\/p><p>[&#8230;]<\/p><p>Swift&rsquo;s C bridging is first-class; <code>struct tm<\/code> and <code>timegm(3)<\/code> are right there. After changing the code to use those, the whole <code>String<\/code> to <code>Date<\/code> conversion runs completely without heap allocations and it&rsquo;s around 6&#x2013;7 times faster than when doing the detour via <code>DateComponents<\/code>.<\/p><p>The final result, according to <a href=\"https:\/\/github.com\/ordo-one\/package-benchmark\">Benchmark<\/a>, is maybe around 15x the speed of the Foundation parsers. I&rsquo;m pretty happy with it. It&rsquo;s available as a <a href=\"https:\/\/swiftpackageindex.com\/juri\/Parse3339\">Swift package<\/a>, there&rsquo;s <a href=\"https:\/\/swiftpackageindex.com\/juri\/Parse3339\/main\/documentation\/parse3339\">documentation<\/a>, and if you need something different or don&rsquo;t feel like using a package, all the parsing code is in just one file you can copy over to your project.<\/p><\/blockquote>\n<p>You can set set it as a <code>JSONDecoder.DateDecodingStrategy<\/code>.<\/p>\n\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/04\/27\/swift-foundation-preview\/\">Swift Foundation Preview<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2013\/09\/10\/date-parsing-performance-nsdateformatter-vs-sqlite\/\">Date Parsing Performance: NSDateFormatter vs. SQLite<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Juri Pakaste (Mastodon): It&rsquo;s well known that DateFormatter, the main timestamp formatter and parser Apple ships in Foundation, is not particularly fast. It&rsquo;s flexible and it&rsquo;s correct, but it takes its time. The newer ISO8601DateFormatter has similar performance.[&#8230;]Swift&rsquo;s C bridging is first-class; struct tm and timegm(3) are right there. After changing the code to use [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2023-07-21T20:13:55Z","apple_news_api_id":"1906d4c5-8ae5-4219-bb94-a5c6405ad520","apple_news_api_modified_at":"2023-07-21T20:13:55Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/AGQbUxYrlQhm7lKXGQFrVIA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[45,31,2185,507,30,2223,568,74,138,270,71,1774,901],"class_list":["post-40125","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-c","tag-ios","tag-ios-16","tag-json","tag-mac","tag-macos-13-ventura","tag-nsdateformatter","tag-opensource","tag-optimization","tag-parser","tag-programming","tag-swift-codable","tag-swift-programming-language"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=40125"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40125\/revisions"}],"predecessor-version":[{"id":40126,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/40125\/revisions\/40126"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=40125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=40125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=40125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}