我不知道有什麼辦法說服人放棄一種語言,用另外一種。不是由於咱們無法客觀比較,而是通常人們會由於各類緣由拒絕客觀比較。html
我在騰訊工做的時候,咱們團隊和深圳一個團隊合併。我注意到深圳一位同事用Scala,寫的程序相對用Java簡練清晰,讓人眼前一亮。我所以專門學習了一段時間Scala。於此同時,我也在學習Go。兩個學習過程同時開始,沒有什麼偏見。可是後來開始開發Peacock(http://arxiv.org/abs/1405.4402)的時候我決定用Go,而不是Scala。緣由有二:程序員
- JVM程序dockerization的成本過高了:每一個docker container裏得安裝JVM和標準庫,花掉幾百MB。一臺機器若是跑100個container,一個機羣100臺機器,一個月要爲此給Google Compute Engine或者Amazon AWS多付多少錢?程序員能夠不算帳,老闆可不行。我在「在將來,Go語言可否撼動Java在Android、Hadoop大數據、雲計算領域的地位? - 王益的回答」裏也提到這個問題。不用container技術能夠嗎?這能夠作另一個問題討論了。只提醒一點:Docker用的Linux kernel cgroup系統調用是2007年Google Borg的開發者貢獻給Linus的,而Google Borg是Google MapReduce框架的代碼量只有Hadoop的百分之一,而功能卻強大得多的根本緣由。更詳細的討論請見這裏:分佈式機器學習的故事:Docker改變世界 - Occam's Razor - 知乎專欄。
- Scala的併發語法(和其餘不少想法)直接借鑑於functional programming languages學術研究成果,不夠貼近工程須要。12年前,個人同窗王垠教了我DrScheme(如今叫作Racket了)。這是MIT開發的計算機系本科生的啓蒙語言。其中有一種語法叫future,也就是Scala裏支持併發的語法。Future是1972年就寫進書裏了《google.com 的頁面》的。它要求一個併發單元最後會返回,而且要返回一個值。這個要求很符合pure functional programming(程序裏除了IO不容許有side effect)的調調,可是不符合實際工程工做須要——我要起一個併發單元執行一個Web server,這事兒顯然就沒有什麼返回值。Go的goroutine顯然更務實——不須要返回什麼值。那結果怎麼傳回來呢?用channel啊。實際上,goroutine + channel能夠徹底復現future語法:只須要把一個future定義爲一個返回channel的goroutine便可——代碼行數都和Scala同樣。請看這裏的例子:http://www.golangpatterns.info/concurrency/futures。
Peacock如今已經在騰訊廣告系統和其餘產品裏應用。它的訓練系統運行在數百臺機器上,一個任務裏的併發單元以百萬計。不少大規模並行機器學習系統的併發規模都如此甚至更大,包括Google Machine Translation背後的language model training system,以及廣告點擊率預估系統(請參見:Research Blog: Lessons learned developing a practical large scale machine learning system)。在這樣的架構下,上述兩個因素就成了決定性因素了。golang
回到主題。我不肯定Scala任什麼時候候都比Go好用,可是上述實踐讓我基本明白,大規模並行系統的開發仍是用Go比較現實。雖然我看到不少朋友說JVM語言的「生態好」,可是恐怕這很快就會隨着Docker、etcd、CoreOS和Kubernetes引導開源社區而變成過去式了,因此我不敢把「生態好」當作一個重要因素來驗證Scala更適合開發大規模併發系統。docker