我是從 2015 年開(kāi)始接觸 Golang,并在之后開(kāi)始在某出行公司的線上環(huán)境大規(guī)模使用,同時(shí)個(gè)人還利用個(gè)人時(shí)間深入研究過(guò) Golang 的底層實(shí)現(xiàn)機(jī)制,包括內(nèi)存管理、GC 機(jī)制、Runtime Scheduler、Interface、Channel 等。這篇文章力求客觀的討論一下 Golang 的利弊。
優(yōu)點(diǎn)
1. 簡(jiǎn)單
簡(jiǎn)單應(yīng)該是 Golang 最大的優(yōu)勢(shì)。Golang 的語(yǔ)言特性簡(jiǎn)單,學(xué)習(xí)周期短,熟悉其他編程語(yǔ)言的開(kāi)發(fā)者基本都可以在短時(shí)間學(xué)會(huì)并寫(xiě)出各方面都還不錯(cuò)的代碼。所謂各方面都還不錯(cuò)是說(shuō)新手開(kāi)發(fā)者寫(xiě)出來(lái)的代碼和一些有經(jīng)驗(yàn)的開(kāi)發(fā)者寫(xiě)出來(lái)的代碼差別并不會(huì)太大。
Golang 語(yǔ)言層面上的簡(jiǎn)潔性讓一些新手程序員也能寫(xiě)出性能不錯(cuò),bug 不多的程序,這個(gè)相比其他高級(jí)語(yǔ)言,比如 C++,是一個(gè)非常大的提升。MIT 的一個(gè)非常有名的課程 6.824 最開(kāi)始使用功能的 C++,后來(lái)改成了 Golang,就是為了讓大家可以專(zhuān)注于分布式算法本身,而不是陷入到語(yǔ)言細(xì)節(jié)的調(diào)試當(dāng)中去。
2.兼顧開(kāi)發(fā)效率和性能
Golang 由于豐富的原生庫(kù)和周邊生態(tài)的支持,開(kāi)發(fā)效率甚至可以比肩 Python。很多公司早期,或者項(xiàng)目早期的時(shí)候?yàn)榱粟s開(kāi)發(fā)進(jìn)度都會(huì)將開(kāi)發(fā)效率放在第一位,比如 Python,PHP 這種動(dòng)態(tài)語(yǔ)言。但是動(dòng)態(tài)語(yǔ)言的性能劣勢(shì)非常明顯?,F(xiàn)在的一個(gè)好現(xiàn)象就是 Golang 已經(jīng)越來(lái)越多的被小公司采用了,畢竟寫(xiě)一個(gè) http server 不過(guò)三行代碼。
另外在開(kāi)發(fā)效率的前提下,Golang 還具有非常高的性能。這一方面得益于靜態(tài)語(yǔ)言,另一方面和其本身的語(yǔ)言設(shè)計(jì)也有很多關(guān)系。但是這里說(shuō)的非常高的性能有點(diǎn)不太嚴(yán)謹(jǐn),相比 C++/Java 這種老牌的高級(jí)語(yǔ)言,在某些場(chǎng)景下的 benchmark 還是要略遜一籌的。
3. 語(yǔ)言級(jí)別的特性支持
所謂語(yǔ)言級(jí)別的并發(fā)支持,就是使用 go func 直接啟動(dòng)一個(gè) goroutine,外加 select/chan 等周邊。在沒(méi)有語(yǔ)言級(jí)別的支持之前的異步編程簡(jiǎn)直就是 callback 噩夢(mèng)。記得云風(fēng)大神之前對(duì) Golang 的一段評(píng)價(jià):
我發(fā)現(xiàn)我花了四年時(shí)間錘煉自己用 C 語(yǔ)言構(gòu)建系統(tǒng)的能力,試圖找到一個(gè)規(guī)范,可以更好的編寫(xiě)軟件。結(jié)果發(fā)現(xiàn)只是對(duì) Go 的模仿。缺乏語(yǔ)言層面的支持,只能是一個(gè)拙劣的模仿?!?云風(fēng)
現(xiàn)在很多人使用一門(mén)新語(yǔ)言的時(shí)候,有時(shí)候還會(huì)問(wèn):“有對(duì)應(yīng)的 coroutine 庫(kù)嗎?” Golang 的語(yǔ)言層面的支持極大的解放了開(kāi)發(fā)者的心智負(fù)擔(dān)。
缺點(diǎn)
1. runtime
支持 runtime 的編程語(yǔ)言一個(gè)無(wú)法繞開(kāi)的問(wèn)題就是 runtime 帶來(lái)的一系列問(wèn)題,比如性能損耗。在 rust 語(yǔ)言介紹自己的優(yōu)勢(shì)的時(shí)候有一點(diǎn)就是 no runtime。
Golang 的線程模型調(diào)度是 M:N,runtime 調(diào)度模型是 GMP 模型,偽搶占式的。簡(jiǎn)單點(diǎn)來(lái)說(shuō)就是 runtime scheduler 可以類(lèi)比成操作系統(tǒng),但是缺乏硬件層面上對(duì)操作系統(tǒng)的支持,比如硬件中斷,這就對(duì) sheduler 的設(shè)計(jì)要求的非常高,但是 Golang 的實(shí)現(xiàn)并沒(méi)有想象中的那么好。
2.并不能做到真正高并發(fā)高性能
Golang 的高并發(fā)使用原生庫(kù)來(lái)實(shí)現(xiàn)的話一般都是通過(guò)多 goroutine + select/channel,但是我們看 channel 源碼,發(fā)現(xiàn)這個(gè)東西就是一個(gè)隊(duì)列+一把鎖。這也就意味著無(wú)法避免多個(gè) goroutine 帶來(lái)的競(jìng)爭(zhēng)問(wèn)題。我之前測(cè)試過(guò)在多個(gè) goroutine 競(jìng)爭(zhēng)同一個(gè) channel 的時(shí)候,性能急劇下降。所以很多高性能的高并發(fā)程序如果是用 Golang 來(lái)寫(xiě),很多都會(huì)避免使用 channel 來(lái)傳遞數(shù)據(jù),而是借用類(lèi)似 disruptor 的 ringbuffer 技術(shù)。
但是這并不是說(shuō) Golang 在高并發(fā)場(chǎng)景下性能不行,對(duì)于日常的 io 密集型的 web server,可以說(shuō)性能是足夠了。
其他
這里談一下 Golang 自問(wèn)世以來(lái)一直被詬病的幾個(gè)問(wèn)題。
1. GC
大概從 1.0 版本以來(lái),GC 就一直被詬病。值得欣慰的是,Golang 的 GC 一直在發(fā)展,基本在每個(gè)版本都有一定的改進(jìn)。1.8 版本是 GC 的一個(gè)里程碑,使用并發(fā)三色標(biāo)記法的 GC 算法的stw 時(shí)間甚至達(dá)到了微秒級(jí)。目前社區(qū)貌似在討論分代 GC 的方案,這個(gè)后面專(zhuān)門(mén)寫(xiě)一篇文章細(xì)說(shuō)。
2. 包管理
包管理也是一直被詬病,主要是一直沒(méi)有一個(gè)官方的解決方案。直到去年官方終于開(kāi)始有行動(dòng)了,推出了 module,相對(duì)來(lái)說(shuō)還是一個(gè)很不錯(cuò)的方案。
3.泛型
Golang 沒(méi)有支持泛型的很大一個(gè)原因是泛型太復(fù)雜。盡管很多人說(shuō) interface 也能實(shí)現(xiàn)泛型功能,但是這個(gè)泛型還是有一些本質(zhì)的區(qū)別的。沒(méi)有泛型確實(shí)是一個(gè)減分項(xiàng)。
-
源碼
+關(guān)注
關(guān)注
8文章
632瀏覽量
29110 -
效率
+關(guān)注
關(guān)注
0文章
146瀏覽量
20026 -
性能
+關(guān)注
關(guān)注
0文章
270瀏覽量
18950
原文標(biāo)題:如何客觀評(píng)價(jià) Go 語(yǔ)言?
文章出處:【微信號(hào):LinuxHub,微信公眾號(hào):Linux愛(ài)好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論