sscanf() 與 strlen() 的故事繼續發展

昨天在「GTA 的啟動讀取效能問題」這邊提到了 sscanf()strlen() 的問題,剛剛在 Hacker News Daily 上又看到一篇「It Can Happen to You」,在講他自己的專案也中獎。

他提到了一個解法,用 strtof() 取代 sscanf() 讀數字,結果大幅降低了 parsing 的時間:

Replacing the sscanf call with strtof improved startup by nearly a factor of 10: from 1.8 seconds to 199 milliseconds.

文章的最後面題到了不少目前正在進行中的討論與 patch。

首先是 FreeBSD 上的 patch 已經在測試:「address a performance problem w/ partial sscanf on long strings...」,裡面可以看到有很小心的在研究會不會造成 performance regression。

然後是 glibc 這邊,在 2014 年就有被開了一張票提出來:「Bug 17577 - sscanf extremely slow on large strings」,不過下面只是多了幾個 comment,目前沒有任何進度。

然後是 cppreference.com 上的「std::scanf, std::fscanf, std::sscanf」頁面則是加注了複雜度的問題:

Complexity

Not guaranteed. Notably, some implementations of sscanf are O(N), where N = std::strlen(buffer) [1]. For performant string parsing, see std::from_chars.

感覺接下來應該還會有更多人提出自己的災情,或是有人發現某個跑很慢的專案也是因為這個原因...