原创 性能優化陷阱之hash真的比strcmp快嗎

最近網上衝浪的時候看到有人分享了自己最近一次性能優化的經驗。我向來對性能是比較敏感的,所以就點進去看了。 然而我越看越覺得蹊蹺,但本着“性能問題和性能優化要靠性能測試做依據”,我不能憑空懷疑別人吧,所以我做了完整的測試並寫下了這篇文章。 可

原创 因爲我的一次疏忽而帶來的golang1.23新特性

距離golang 1.23發佈還有兩個月不到,按照慣例很快要進入1.23的功能凍結期了。在凍結期間不會再添加新功能,已經添加的功能不出大的意外一般也不會被移除。這正好可以讓我們提前嚐鮮這些即將到來的新特性。 今天要說的就是1.23中對//g

原创 Linux上執行內存中的腳本和程序

在Linux中可以不需要有腳本或者二進制程序的文件在文件系統上實際存在,只需要有對應的數據在內存中,就有辦法執行這些腳本和程序。 原理其實很簡單,Linux裏有辦法把某塊內存映射成文件描述符,對於每一個文件描述符,Linux會在/proc/

原创 C++ lambda的重載

先說結論,lambda是不能重載的(至少到c++23依舊如此,以後會怎麼樣沒人知道)。而且即使代碼完全一樣的兩個lambda也會有完全不同的類型。 但雖然不能直接實現lambda重載,我們有辦法去模擬。 在介紹怎麼模擬之前,我們先看看c++

原创 C++裏也有菱形運算符?

最近在翻《c++函數式編程》的時候看到有一小節在說c++14新增了“菱形運算符”。我尋思c++裏好像沒什麼運算符叫這名字啊,而且c++14新增的功能很少,我也不記得有添加這種語法特性。一瞬間我有些懷疑我的記憶了,所以爲了查漏補缺,我寫了這篇

原创 golang gc的內部優化

今天講一個常見的gc compiler(也就是官方版本的go編譯器和runtime)在垃圾回收的掃描標記階段做的優化。 我對這個優化的描述印象最深的是在bigcache的註釋裏,大致內容是如果map的鍵值都不包含指針,那麼gc掃描的時候不管

原创 errgroup的常見誤用

errgroup想必稍有經驗的golang程序員都應該聽說過,實際項目中用過的也應該不在少數。它和sync.WaitGroup類似,都可以發起執行並等待一組協程直到所有協程運行結束。除此之外errgroup還可以在協程出錯時取消當前的con

原创 golang chan傳遞數據的性能開銷

這篇文章並不討論chan因爲加鎖解鎖以及爲了維持內存模型定義的行爲而付出的運行時開銷。 這篇文章要探討的是chan在接收和發送數據時因爲“複製”而產生的開銷。 在做性能測試前先複習點基礎知識。 本文索引 數據是如何在chan裏流動的

原创 我們能從PEP 703中學到什麼

PEP703是未來去除GIL的計劃,當然現在提案還在繼續修改,但大致方向確定了。 對於實現細節我沒啥興趣多說,挑幾個我比較在意的點講講。 儘量少依賴原子操作的引用計數 沒了GIL之後會出現兩個以上的線程同時操作同一個Python對象的情況,

原创 golang1.21新特性速覽

經過了半年左右的開發,golang 1.21 在今天早上正式發佈了。 這個版本中有不少重要的新特性和變更,尤其是在泛型相關的代碼上。 因爲有不少大變動,所以建議等第一個patch版本也就是1.21.1出來之後再進行升級,以免遇到一些意外的b

原创 簡單瞭解下最近正火的SwissTable

去年看到字節跳動給golang提了issue建議把map的底層實現改成SwissTable的時候,我就有想寫這篇博客了,不過因爲種種原因一直拖着。 直到最近遇golang官方開始討論爲了是否要接受SwissTable作爲map的默認實現,以

原创 讓golang程序生成coredump文件並進行調試

今天講講怎麼讓golang程序生成coredump文件,並且進行調試的。 別看我寫了不少golang的博客,其實我平時寫c++的時間更多,所以也算和coredump是老相識了。core dump文件實際上是進程在某個時間點時的內存映像,當時

原创 golang中一種不常見的switch語句寫法

最近翻開源代碼的時候看到了一種很有意思的switch用法,分享一下。 注意這裏討論的不是typed switch,也就是case語句後面是類型的那種。 直接看代碼: func (s *systemd) Status() (Status, e

原创 小心golang中的無類型常量

對於無類型常量,可能大家是第一次聽說,但這篇我就不放進拾遺系列裏了。 因爲雖然名字很陌生,但我們每天都在用,每天都有無數潛在的坑被埋下。包括我本人也犯過同樣的錯誤,當時代碼已經合併併發布了,當我意識到出了什麼問題的時候爲時已晚,最後不得不多

原创 golang拾遺:實現一個不可複製類型

這是golang拾遺系列的第六篇。這個系列主要用來記錄一些平時不常見的知識點,偶爾也會實現些有意思的小功能,比如這篇。 golang拾遺系列目錄: golang拾遺:指針和接口 golang拾遺:爲什麼我們需要泛型 golang拾遺:嵌入