全球代碼質(zhì)量驟降,罪魁禍?zhǔn)拙故茿I!1.53億行代碼深度分析報告出爐
AI正在使全球的代碼質(zhì)量下降!
最近,GitClear發(fā)布的一項調(diào)查報告顯示,用AI寫代碼,會讓代碼的質(zhì)量和可維護性不斷下降。
這引起了全網(wǎng)熱烈討論:
「借助AI提供商,您可以將代碼生成速度提高50%(即使是您不理解或無法編寫的代碼),但代價是代碼的質(zhì)量和可持續(xù)性不斷下降?!?/span>
「我們要追求的,到底是質(zhì)量還是速度?」
調(diào)查中,GitClear分析了從2020年1月到2023年12月之間編寫的1.53億行代碼更改數(shù)據(jù),
——1.53億行代碼,是目前已知最大的用于評估代碼質(zhì)量差異的數(shù)據(jù)集。
調(diào)查發(fā)現(xiàn)了什么?我們先看下面這張圖:
圖中展示了4年中的代碼改動率——編寫后不到兩周就被撤銷或更新的代碼行百分比,——深色部分表示受AI代碼生成工具影響的時間。
調(diào)查中同樣發(fā)現(xiàn),「新增代碼」和「復(fù)制粘貼代碼」的比例相對于「更新」、「刪除」和「移動」代碼的比例在增加。
這貌似說明開發(fā)人員在大量使用Copilot等AI代碼生成工具,快速生成了大量代碼,但隨后發(fā)現(xiàn)了代碼中的問題,——GitClear的報告預(yù)計在2024年,這個代碼改動率將達(dá)到2021年AI出現(xiàn)前的兩倍。
另外一點就是,AI代碼生成工具不太理會人類程序員的一些原則(比如「重復(fù)造輪子」這件事),也就造成了代碼庫中越來越多的重復(fù)代碼。
——不過很多碼農(nóng)都是「CV程序員」,這樣看來,AI也算是學(xué)到了精髓。
2023年,GitHub Copilot大放異彩。在短短不到兩年時間內(nèi),這款A(yù)I編程助手從一個「原型」迅速成長為「核心工具」,被全球數(shù)百萬開發(fā)者在數(shù)十萬家企業(yè)中廣泛應(yīng)用,開啟了coding的新時代。
對此,GitHub發(fā)表了多篇研究論文,探討了AI在軟件開發(fā)領(lǐng)域的增長與影響。
速度提升55%,GDP增加1.5萬億
研究表明,使用Copilot的開發(fā)者編碼速度可以提高「55%」,導(dǎo)致總的代碼量增加了46%,并且為全球創(chuàng)造了1.5萬億美元GDP。
有了這樣的成績,也就不難理解為什么GitHub的CEO Thomas Dohmke,會在繁忙的工作之余,專門撰寫關(guān)于AI革命的文章。
在2023年2月Copilot個人版用戶超過一百萬之后,GitHub又推出了GitHub Copilot for Business版本。
那么,有多少開發(fā)者在用AI來編寫代碼呢?
GitHub與Wakefield Research在2023年6月的一項研究中指出,92%的美國大型公司的開發(fā)者表示他們使用了AI編程工具。并且有70%的開發(fā)者認(rèn)為使用AI帶來了明顯的好處。
不過,O’Reilly Publishing在2023年8月給出的調(diào)查數(shù)據(jù)顯示,67%的開發(fā)者沒有用過ChatGPT或Copilot。不管怎樣,GitHub在市場上仍有巨大的潛力等待挖掘。
——然而,大語言模型(LLM)生成的代碼引發(fā)的一個問題是:
這些代碼的質(zhì)量和可維護性到底怎么樣?
面對AI滔滔不絕吐出的一大堆代碼,程序員似乎不太容易發(fā)現(xiàn)其中的問題——畢竟都不是自己寫的。
還有,眾所周知,當(dāng)程序員接手前人留下來的*山代碼時,應(yīng)該遵守的「潛規(guī)則」是:
如果這個代碼能夠正常運行,就千萬不要妄想去重構(gòu)。
AI生成代碼背后的挑戰(zhàn)
無法否認(rèn),Copilot實實在在的提升了開發(fā)者的編碼效率。GitHub的研究顯示,使用Copilot的開發(fā)者滿意度提升了75%。
做初期產(chǎn)品開發(fā)的人是滿意了,可后面負(fù)責(zé)長期維護的人就蛋疼了。
資深代碼研究者Adam Tornhill(著有《代碼即犯罪現(xiàn)場》)對此持保留態(tài)度:
使用Copilot可以使代碼編寫速度提高55%,但如果是本就不應(yīng)該編寫的代碼呢?
如《Clean Code: A Handbook of Agile Software Craftsmanship》一書的作者Robert Martin所說,代碼的閱讀時間是編寫時間的十倍??焖倬帉懺愀獾拇a,意味著給后來的代碼閱讀者帶來了巨大的負(fù)擔(dān)。
此外,AI代碼助手還帶來了其他問題:
比如代碼助手擅長生成代碼,卻不擅長修改;當(dāng)有多個生成工具給出建議時,評估哪個更好是很耗費時間的;
最后,AI代碼助手與開發(fā)者的動機可能不同,對于代碼優(yōu)化來說,AI往往傾向于提出最有可能被接受的建議。
所以,相比于經(jīng)驗更豐富的開發(fā)人員,初級開發(fā)者更傾向于接受AI給出的代碼建議:
而老鳥們深知,隨著時間推移,代碼的維護成本會越來越高。
代碼操作介紹
GitClear將代碼變更分為七個類別(研究中涉及前六種):
1. 新增代碼:首次提交的代碼行,代碼行是全新的,不包括對現(xiàn)有代碼行的小幅修改,也不包括那些被添加、移除后又重新添加的代碼行。
2. 刪除代碼:被刪除并提交的代碼行,且至少在隨后的兩周內(nèi)未被重新加入。
3. 移動代碼:將一行代碼剪切并粘貼到新文件或同一文件內(nèi)的新函數(shù)中。「移動」的操作僅涉及位置的變換,代碼內(nèi)容不發(fā)生改變。
4. 更新代碼:修改大約三個或更少的單詞來更改原有代碼行。
5. 查找/替換代碼:從三個或更多位置移除相同字符串,并用一致的內(nèi)容進(jìn)行替換。
6. 復(fù)制/粘貼代碼:在一次提交中,將相同的代碼行內(nèi)容復(fù)制到多個文件或函數(shù)中。
7. 無操作代碼:指一些微小的代碼變更,比如空格或同一代碼塊內(nèi)行號的變化。
GitClear自2020年起根據(jù)這些操作對git倉庫進(jìn)行分類,并在Diff Delta文檔中提供了代碼操作的具體示例。
截至2024年1月,GitClear分析并分類了大約十億行代碼,這些代碼來自商業(yè)客戶(如 NextGen Health, Verizon)和流行的開源倉庫(如 Facebook React, Google Chrome)。
其中,1.53億行代碼為有意義的變更,被用于本研究。
最后,還有一個單獨的定義叫做「攪動」(churn),意思是代碼被創(chuàng)建、推送到git倉庫后,在接下來的兩周內(nèi)被撤銷或大幅修改。
——也就是咱們最開始分析的那張圖,可以將「攪動」理解為,作者一開始編寫、提交并推送到公司git倉庫的代碼有問題,后來發(fā)現(xiàn)了。
數(shù)據(jù)分析
下表根據(jù)GitClear的數(shù)據(jù),分析了不同的代碼行操作數(shù)量,并按照代碼的編寫年份進(jìn)行分類。
表中的前六項就是上面提到的代碼變更的前六個類別,而最后一項是「攪動」。
將表格數(shù)據(jù)繪制成下面的圖表,可以更清晰地看出各種代碼操作類型的變化趨勢,比如,圖表中的淺藍(lán)色細(xì)線顯示了「Churn」類型代碼的變化:
對于2024年的預(yù)測,這里使用OpenAI的gpt-4-1106-preview助手,對現(xiàn)有數(shù)據(jù)進(jìn)行二次回歸分析。
通過對比2022年與2023年的操作頻率差異,識別出了三個可能影響代碼質(zhì)量的警示信號:
危險信號
2023 年,我們目睹了代碼攪動、移動和復(fù)制粘貼方面的顯著變化,這些變化背后的含義值得深入探討。
代碼攪動的新趨勢
「代碼攪動(Churn)」反映了推送到代碼倉庫后,在接下來的兩周內(nèi)被撤銷、移除或更新的代碼比例。
過去,當(dāng)開發(fā)者完全自主編寫代碼時,這種情況相對罕見——2023年之前,僅有3-4%的代碼會發(fā)生攪動。
然而,2022年,隨著Copilot的首次亮相和ChatGPT的問世,代碼攪動率的預(yù)兆性跳升至9%。
2022至2023年間,AI助手的崛起與倉庫中錯誤代碼的增加密切相關(guān)。
假設(shè)Copilot在2021年的普及率為0%,2022年為5-10%,2023年達(dá)到30%,這些變量之間的Pearson相關(guān)系數(shù)高達(dá)0.98,顯示了它們的同步增長。
隨著代碼攪動成為常態(tài),錯誤代碼部署到生產(chǎn)環(huán)境的風(fēng)險也隨之增大。如果這一趨勢持續(xù)到2024年,超過7%的代碼更改可能會在兩周內(nèi)被撤銷,這是2021年的兩倍。
據(jù)此,報告預(yù)計Google DORA在年底發(fā)布的「2024 Devops 狀態(tài)」報告中,將顯示「變更失敗率」的上升。當(dāng)然前提是研究包含了2023年使用AI輔助的開發(fā)者數(shù)據(jù)。
代碼移動減少,反映出重構(gòu)和復(fù)用的減少
代碼移動通常出現(xiàn)在對現(xiàn)有代碼系統(tǒng)進(jìn)行重構(gòu)時。
重構(gòu)系統(tǒng),特別是代碼的移動,是代碼復(fù)用的基礎(chǔ)。隨著產(chǎn)品范圍擴大,開發(fā)者會將現(xiàn)有代碼重組到新的模塊和文件中,以便新功能復(fù)用。
對經(jīng)驗豐富的開發(fā)者而言,代碼復(fù)用的好處顯而易見——與新增代碼相比,復(fù)用的代碼已經(jīng)過測試并在生產(chǎn)環(huán)境中證明其穩(wěn)定性。
復(fù)用的代碼往往已被多人修改,更可能包含文檔,這有助于新人更快理解模塊。
隨著標(biāo)記為「復(fù)制粘貼」的代碼增加,AI助手似乎在抑制代碼的復(fù)用,而是提供了一種重復(fù)現(xiàn)有代碼的簡單方式,而不是鼓勵重構(gòu)和遵循「不要重復(fù)自己(DRY)」的原則。
復(fù)制粘貼代碼增多,預(yù)示著未來的維護困難
長期來看,復(fù)制粘貼代碼可能是對代碼可維護性的影響最大的因素。
當(dāng)代碼行被重復(fù)使用時,本質(zhì)上意味著「我沒有時間去評估之前的實現(xiàn)方式」。
選擇復(fù)制粘貼新代碼而沒有復(fù)用代碼,會使得未來的維護工作變得更加困難,因為需要整合那些實現(xiàn)相同功能的平行代碼的實現(xiàn)方式。
大多數(shù)開發(fā)者更喜歡「實現(xiàn)新功能」而不是「解讀可能可復(fù)用的代碼」,因此復(fù)制粘貼的代碼往往會長時間存在。
而且在經(jīng)驗缺乏的團隊中,可能沒有有能力且有權(quán)威的代碼維護者來刪除那些重復(fù)的代碼。
即便是資深開發(fā)者,要充分理解代碼從而刪除某些重復(fù)的代碼,所需的努力也是非常巨大的。
如果沒有CTO或工程負(fù)責(zé)人主動安排時間來減輕技術(shù)債,那么「自上而下的時間壓力」就會成為新添加的復(fù)制粘貼代碼,讓這些代碼永遠(yuǎn)無法整合到改善長期開發(fā)速度的庫中的又一個原因。
由于GitClear只統(tǒng)計單次提交中的重復(fù)代碼,2023年測得的11%復(fù)制粘貼比例可能只是只是今年復(fù)制粘貼代碼非常小的一部分。
總結(jié)
根據(jù)報告評估的兩個關(guān)鍵數(shù)據(jù)點顯示,2023年代碼質(zhì)量出現(xiàn)了嚴(yán)重的下降。這種情況與大語言模型(LLM)的廣泛應(yīng)用,尤其是AI代碼助手的流行有直接關(guān)聯(lián)。
GitHub與Wakefield Research在2023年的一項調(diào)查反映出開發(fā)者已經(jīng)意識到代碼質(zhì)量的下降。
當(dāng)被問及「在沒有AI輔助的情況下,你認(rèn)為應(yīng)該評估哪些指標(biāo)?」他們最關(guān)注的是「協(xié)作與溝通」,緊隨其后的是「代碼質(zhì)量」。
而當(dāng)問題變?yōu)椤冈谑褂肁I輔助時,你認(rèn)為應(yīng)該評估哪些指標(biāo)?」他們的答案發(fā)生了變化,其中「代碼質(zhì)量」躍升為最受關(guān)注的問題,「生產(chǎn)環(huán)境中的問題事件」也上升至第三位:
單個開發(fā)者的情況可能無法說明為何「代碼質(zhì)量」和「生產(chǎn)環(huán)境中的問題事件」在使用AI時顯得更加重要,但報告的數(shù)據(jù)揭示了一個可能的原因:
當(dāng)開發(fā)者被一波又一波看似合適、能短期內(nèi)解決問題的建議所淹沒時,他們很容易不斷增加代碼量,卻忽視了代碼的優(yōu)化和復(fù)用。
——如果按一下Tab鍵就能解決當(dāng)前的問題,為什么要費心思管以后的事情?
AI助手和Copilot將如何重塑開發(fā)者的角色?隨著AI技術(shù)的廣泛應(yīng)用,毫無疑問,我們已經(jīng)進(jìn)入了一個代碼增長速度空前的新時代。
那么,2024年的問題可能是:誰來收拾事后的爛攤子?
網(wǎng)友討論
面對AI帶來的「全球代碼質(zhì)量下行」,網(wǎng)友也是深有體會:
譴責(zé)型:「我在兩個月后取消了訂閱(Copilot),因為我花了太多精力去修復(fù)所有代碼錯誤。而且在處理任何復(fù)雜的事情或與SQL有關(guān)的事情時,它基本上是無用的(即使我提前加載了整個模式)。」
大佬型:「寫下所有東西其實要花的功夫少得多,因為我知道自己想寫什么,而且修正自己的錯誤比修正機器人的錯誤更容易」。
悲天憫人型:「我為那些將被這種垃圾徹底擊垮的初學(xué)者而哭泣?!?/span>
中立型:「Copilot能做的事讓我很吃驚,但確實不能說生成的代碼很好。生成的代碼肯定得改,但是確實能幫你省不少時間」。