![]()
新智元報道
編輯:傾傾
【新智元導讀】很多人背著「過早優(yōu)化是萬惡之源」的名言,寫出的卻是處處漏風的代碼。Google傳奇Jeff Dean的這份筆記破了真相:性能不是最后調(diào)出來的,而是你在選第一個容器、敲第一行代碼時,就已經(jīng)注定的物理結(jié)局。
2025年,是個很容易讓人產(chǎn)生錯覺的時間點。
這時算力不再稀缺,云資源隨叫隨到,AI已經(jīng)能寫出準確無誤的代碼。
在這樣的環(huán)境里,「性能」似乎正在悄悄貶值。因為代碼寫得慢一些,好像也沒什么大不了。
就在這種氛圍下,Google的傳奇工程師Jeff Dean更新了一份老文檔:Performance Hints。
![]()
比起一篇炫技的論文,它更像是一份老派工程師的隨筆,里面重新整理了基礎(chǔ)法則。
它反復重申一個事實:計算機底層的物理規(guī)則,從未因為云原生、AI或硬件的進步而改變。
硬件的進步掩蓋了代碼的低效,這些問題會在系統(tǒng)中不斷堆積,直到成為無法繞開的成本。
「過早優(yōu)化」,成了平庸代碼的豁免權(quán)
所有工程師都聽過一句老話:
Premature optimization is the root of all evil.(過早優(yōu)化是萬惡之源)。
它原本是提醒我們,別為了摳幾行代碼,把系統(tǒng)搞成一團亂麻。
但在實踐中,這句話慢慢變了味,成了一個免責口令——只要遇到性能質(zhì)疑,一句「別過早優(yōu)化」就能把所有問題擋回去。
結(jié)果走向了另一個極端:寫代碼時,性能被整體忽略。抽象可以多一層,數(shù)據(jù)可以多拷貝一次,API可以寫得更「通用」。
![]()
瑞士奶酪模型:單個小漏洞沒事,但是一層層疊加,對齊了會出大事
大家總覺得將來有profiler,等真慢下來再說。
可等系統(tǒng)上線,流量涌入,響應(yīng)開始變拖沓,大家終于打開性能分析圖,卻發(fā)現(xiàn)屏幕上什么都沒有。
沒有一個函數(shù)占掉40%的時間,沒有明顯的性能熱點。你看到的只有一張異常平坦的火焰圖——每一層都慢一點,每一個看似無關(guān)緊要的選擇,都給未來埋下隱患。
你很難指出哪里出了錯,因為問題從一開始就沒有集中出現(xiàn)——這正是Jeff Dean反復強調(diào)的一種模式。
性能不是被某個錯誤決定拖垮的,而是被一連串「看起來沒問題」的決策慢慢稀釋掉的。
![]()
一旦走到這一步,優(yōu)化會變得異常昂貴,因為你失去了明確的下手點。
所謂「關(guān)鍵的3%」,指的從來不是寫完代碼后再去摳字眼,而是在寫第一行代碼時,就要避開那些雖然方便、但明顯低效的路徑。
這不只是技巧,更像一種素養(yǎng)。真正拉開差距的地方,往往發(fā)生在profiler還沒派上用場之前。
5ns和5ms之間,隔著整個物理世界
如果說前面的區(qū)別發(fā)生在「已經(jīng)來不及了」,那么接下來要說的是:「為什么我們會在一開始就走錯路」。
事實上,很多工程事故并不是因為「不會優(yōu)化」,而是因為對「慢」沒有感覺。
在編輯器里,5ns和5ms看起來只是多了幾個0。縮進一樣,語法一樣,在Code Review時看起來合理合規(guī)。
但在物理世界,這些數(shù)字根本不屬于同一個尺度。
Jeff Dean在清單里列出了一張延遲對照表。一旦把這些數(shù)字還原成現(xiàn)實中的時間,很多所謂的設(shè)計直覺會當場崩塌。
L1緩存命中:約0.5ns,等于微觀世界里的一次脈搏。
分支預(yù)測失敗:5ns,是連續(xù)十次脈搏。
主存訪問:50ns,相當于起個身,走下樓,取了個外賣。
隨機磁盤尋址:10000000ns,相當于從北京一路走到了上海。
![]()
最早由Google工程師整理,Jeff Dean在多次演講中用過這個思路
如果你的方案里出現(xiàn)了一次磁盤尋址,后面無論代碼寫得多優(yōu)雅、邏輯多漂亮,在物理尺度上都已經(jīng)輸透了。
這就是頂級工程師腦子里的「物理地圖」。他們本能地知道:哪些操作屬于同一量級,而哪些操作一旦混進來,系統(tǒng)的節(jié)奏就徹底亂了。
這也是「信封背面估算」(Back-of-the-envelope calculation)的價值所在。
它是一次動手之前的排查:這個方案會觸發(fā)多少次內(nèi)存訪問?有沒有隱藏的分配?循環(huán)里會不會撞上網(wǎng)絡(luò)IO?
如果答案里出現(xiàn)了一個不合時宜的量級,這個方案就應(yīng)該被扔進垃圾桶。
很多性能問題并非「實現(xiàn)得不夠好」,而是選錯了路徑。
一旦建立起這種尺度感,很多無意義的爭論就能一眼看穿。
反直覺的真相:Google大佬的代碼為什么看起來很「土」?
真正拉開差距的地方,不在于「寫得多聰明」,而在于知道哪些地方「不值得聰明」。
翻開這份Performance Hints,我們能發(fā)現(xiàn)一個反直覺的事實:沒有復雜的算法,很多改動看起來都有點「土」。
但這些細碎的選擇,卻被Jeff Dean反復拿出來強調(diào)。
對內(nèi)存的節(jié)制
「尺度感」讓我們意識到分配內(nèi)存的珍貴,在實戰(zhàn)中,這種意識會轉(zhuǎn)化成對容器的極致考究。
為什么他們偏愛InlinedVector?因為在絕大多數(shù)場景下,它根本不碰堆內(nèi)存,數(shù)據(jù)直接躺在棧上。
這帶來的是實實在在的物理收益:少一次分配,多一次緩存命中。
同樣的,使用Arena(內(nèi)存池)也不只是為了管理方便,而是為了讓數(shù)據(jù)在物理內(nèi)存上變得連續(xù),順應(yīng)CPU緩存的節(jié)奏。
對數(shù)據(jù)分布的尊重
所謂的Fast Path(快路徑),本質(zhì)上是承認世界是不均勻的。99%的請求和輸入都比想象中普通。
如果堅持讓每一次調(diào)用都走那條「最通用、最保險」的路,實際上是在用極少數(shù)的邊緣情況,綁架絕大多數(shù)的正常流量。
![]()
清單里提到的UTF-8處理就是一個典型:現(xiàn)實中大量字符串其實只有純ASCII字符。
如果一上來就按完整的解析邏輯走,那每一個字節(jié)都在為萬分之一的極端情況買單。
看一眼,是ASCII就直接放行——這種行為,建立在對數(shù)據(jù)規(guī)律的尊重之上。
對抽象成本的自覺
清單里舉了個例子:把Protobuf邏輯改成原生結(jié)構(gòu)體,性能提升20倍,讓很多人不安。
Protobuf確實解決了跨語言和版本演進的難題,但便利從不是免費的,每一層封裝、每一次解析,都是一筆隱蔽的「抽象稅」。
就像在透支信用卡,你可以盡情購物,可一旦賬單寄來,就要付出相應(yīng)代價。
![]()
抽象并不會消失,只是被編譯器展開,最終落實到一行行具體的實現(xiàn)上。
當抽象層數(shù)不斷疊加,成本也會在底層被一并兌現(xiàn)。
這就是為什么他們建議在熱路徑里避開不必要的層級、避開那些「為了完整而完整」的設(shè)計。
目的是讓你清楚地意識到,你到底在為什么付費。
頂級工程師關(guān)心的,從來不是如何寫出最聰明的代碼,而是如何避免那些本不該出現(xiàn)的開銷。
當你在敲鍵盤時,能對分配、分布、抽象成本保持警惕,很多性能瓶頸在發(fā)生之前,就已經(jīng)被擋在了門外。
想提高性能,就不能對代價視而不見
很多人把性能理解成一種階段性的工作:系統(tǒng)慢了,就開始優(yōu)化;不慢,就先放一邊。
但讀完這份清單,你很難再這樣看待它。
Jeff Dean們反復強調(diào)的,其實不是「如何省下幾納秒」,而是「你是否真正理解自己正在使用的計算資源」。
CPU、內(nèi)存、緩存、磁盤......這些底層的物理規(guī)律并沒有因為云原生或AI的流行而消失,它們只是被包裝得更抽象了。
頂級工程師之所以顯得從容,是因為他們很少走到「火場」里:在寫第一行代碼時,他們就已經(jīng)避開了那些注定昂貴的路徑。
這份Performance Hints讀起來不像教程,更像是一份肌肉記憶。它不要求你處處極限優(yōu)化,而是要求你在做決策時,不要假裝不知道代價。
也許真正的分界線一直是——當你寫下一個循環(huán)、設(shè)計一個數(shù)據(jù)結(jié)構(gòu)、決定要不要多加一層時,腦海中是否浮現(xiàn)出那張時間和尺度的地圖。
一旦有了它,很多平庸的代碼,你就再也寫不下去了。
參考資料:
https://x.com/JeffDean/status/2002089534188892256?s=20
秒追ASI
?點贊、轉(zhuǎn)發(fā)、在看一鍵三連?
點亮星標,鎖定新智元極速推送!
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.