成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

放棄Python轉向Go語言:我們找到了以下9大理由

開發 開發工具
今年 Stream 團隊的主要編程語言從 Python 轉向了 Go。本文解釋了其背后的九大原因以及如何做好這一轉換。

轉用一門新語言通常是一項大決策,尤其是當你的團隊成員中只有一個使用過它時。今年 Stream 團隊的主要編程語言從 Python 轉向了 Go。本文解釋了其背后的九大原因以及如何做好這一轉換。

一、為什么使用 Go

原因 1:性能

[[206817]]

Go 極其地快。其性能與 Java 或 C++相似。在我們的使用中,Go 一般比 Python 要快 30 倍。以下是 Go 與 Java 之間的基準比較:

原因 2:語言性能很重要

對很多應用來說,編程語言只是簡單充當了其與數據集之間的膠水。語言本身的性能常常無關輕重。

但是 Stream 是一個 API 提供商,服務于世界 500 強以及超過 2 億的終端用戶。數年來我們已經優化了 Cassandra、PostgreSQL、Redis 等等,然而最終抵達了所使用語言的極限。

Python 非常棒,但是其在序列化/去序列化、排序和聚合中表現欠佳。我們經常會遇到這樣的問題:Cassandra 用時 1ms 檢索了數據,Python 卻需要 10ms 將其轉化成對象。

原因 3:開發者效率&不要過于創新

看一下***的入門教程《開始學習 Go 語言》

(http://howistart.org/posts/go/1/)中的一小段代碼:

  1. package main 
  2. type openWeatherMap struct{}func (w openWeatherMap) temperature(city string) (float64, error) {  
  3. resp, err :http.Get("http://api.openweathermap.org/data/2.5/weather?APPID=YOUR_API_KEY&q=" + city)  
  4. if err != nil {  
  5. return 0, err  
  6.  
  7. defer resp.Body.Close() 
  8.  
  9. var d struct {  
  10. Main struct { 
  11. Kelvin float64 `json:"temp"`  
  12. } `json:"main"` 
  13.  
  14. if err :json.NewDecoder(resp.Body).Decode(&d); err != nil {  
  15. return 0, err  
  16.  
  17. log.Printf("openWeatherMap: %s: %.2f", city, d.Main.Kelvin)  
  18. return d.Main.Kelvin, nil} 

如果你是一個新手,看到這段代碼你并不會感到吃驚。它展示了多種賦值、數據結構、指針、格式化以及內置的 HTTP 庫。

當我***次編程時,我很喜歡使用 Python 的高階功能。Python 允許你創造性地使用正在編寫的代碼,比如,你可以:

  • 在代碼初始化時,使用 MetaClasses 自行注冊類別
  • 置換真假
  • 添加函數到內置函數列表中
  • 通過奇妙的方法重載運算符

毋庸置疑這些代碼很有趣,但也使得在讀取其他人的工作時,代碼變得難以理解。

Go 強迫你堅持打牢基礎,這也就為讀取任意代碼帶來了便利,并能很快搞明白當下發生的事情。

注意:當然如何容易還是要取決于你的使用案例。如果你要創建一個基本的 CRUD API,我還是建議你使用 Django + DRF,或者 Rails。

原因 4:并發性&通道

Go 作為一門語言致力于使事情簡單化。它并未引入很多新概念,而是聚焦于打造一門簡單的語言,它使用起來異常快速并且簡單。其唯一的創新之處是 goroutines 和通道。Goroutines 是 Go 面向線程的輕量級方法,而通道是 goroutines 之間通信的優先方式。

創建 Goroutines 的成本很低,只需幾千個字節的額外內存,正由于此,才使得同時運行數百個甚至數千個 goroutines 成為可能。你可以借助通道實現 goroutines 之間的通信。Go 運行時間可以表示所有的復雜性。Goroutines 以及基于通道的并發性方法使其非常容易使用所有可用的 CPU 內核,并處理并發的 IO——所有不帶有復雜的開發。相較于 Python/Java,在一個 goroutine 上運行一個函數需要最小的樣板代碼。你只需使用關鍵詞「go」添加函數調用:

  1. package main 
  2. import ( 
  3.    "fmt" 
  4.    "time")func say(s string) { 
  5.    for i :0; i < 5; i++ { 
  6.        time.Sleep(100 * time.Millisecond) 
  7.        fmt.Println(s) 
  8.    }}func main() { 
  9.    go say("world") 
  10.    say("hello")} 

Go 的并發性方法非常容易上手,相較于 Node 也很有趣;在 Node 中,開發者必須密切關注異步代碼的處理。

并發性的另一個優質特性是競賽檢測器,這使其很容易弄清楚異步代碼中是否存在競態條件。下面是一些上手 Go 和通道的很好的資源:

  • https://gobyexample.com/channels
  • https://tour.golang.org/concurrency/2
  • http://guzalexander.com/2013/12/06/golang-channels-tutorial.html
  • https://www.golang-book.com/books/intro/10
  • https://www.goinggo.net/2014/02/the-nature-of-channels-in-go.html

原因 5:快速的編譯時間

當前我們使用 Go 編寫的***微服務的編譯時間只需 6 秒。相較于 Java 和 C++呆滯的編譯速度,Go 的快速編譯時間是一個主要的效率優勢。我熱愛擊劍,但是當我依然記得代碼應該做什么之時,事情已經完成就更好了。

Go 之前的代碼編譯

Go 之前的代碼編譯

原因 6:打造團隊的能力

首先,最明顯的一點是:Go 的開發者遠沒有 C++和 Java 等舊語言多。據知,有 38% 的開發者了解 Java,19.3% 的開發者了解 C++,只有 4.6% 的開發者知道 Go。GitHub 數據表明了相似的趨勢:相較于 Erlang、Scala 和 Elixir,Go 更為流行,但是相較于 Java 和 C++ 就不是了。

幸運的是 Go 非常簡單,且易于學習。它只提供了基本功能而沒有多余。Go 引入的新概念是「defer」聲明,以及內置的帶有 goroutines 和通道的并發性管理。正是由于 Go 的簡單性,任何的 Python、Elixir、C++、Scala 或者 Java 開發者皆可在一月內組建成一個高效的 Go 團隊。

原因 7:強大的生態系統

對我們這么大小的團隊(大約 20 人)而言,生態系統很重要。如果你需要重做每塊功能,那就無法為客戶創造收益了。Go 有著強大的工具支持,面向 Redis、RabbitMQ、PostgreSQL、Template parsing、Task scheduling、Expression parsing 和 RocksDB 的穩定的庫。

Go 的生態系統相比于 Rust、Elixir 這樣的語言有很大的優勢。當然,它又略遜于 Java、Python 或 Node 這樣的語言,但它很穩定,而且你會發現在很多基礎需求上,已經有高質量的文件包可用了。

原因 8:GOFMT,強制代碼格式

Gofmt 是一種強大的命令行功能,內建在 Go 的編譯器中來規定代碼的格式。從功能上看,它類似于 Python 的 autopep8。格式一致很重要,但實際的格式標準并不總是非常重要。Gofmt 用一種官方的形式規格代碼,避免了不必要的討論。

原因 9:gRPC 和 Protocol Buffers

Go 語言對 protocol buffers 和 gRPC 有***的支持。這兩個工具能一起友好地工作以構建需要通過 RPC 進行通信的微服務器(microservices)。我們只需要寫一個清單(manifest)就能定義 RPC 調用發生的情況和參數,然后從該清單將自動生成服務器和客戶端代碼。這樣產生代碼不僅快速,同時網絡占用也非常少。

從相同的清單,我們可以從不同的語言生成客戶端代碼,例如 C++、Java、Python 和 Ruby。因此內部通信的 RESET 端點不會產生分歧,我們每次也就需要編寫幾乎相同的客戶端和服務器代碼。

二、使用 Go 語言的缺點

缺點 1:缺少框架

Go 語言沒有一個主要的框架,如 Ruby 的 Rails 框架、Python 的 Django 框架或 PHP 的 Laravel。這是 Go 語言社區激烈討論的問題,因為許多人認為我們不應該從使用框架開始。在很多案例情況中確實如此,但如果只是希望構建一個簡單的 CRUD API,那么使用 Django/DJRF、Rails Laravel 或 Phoenix 將簡單地多。

缺點 2:錯誤處理

Go 語言通過函數和預期的調用代碼簡單地返回錯誤(或返回調用堆棧)而幫助開發者處理編譯報錯。雖然這種方法是有效的,但很容易丟失錯誤發生的范圍,因此我們也很難向用戶提供有意義的錯誤信息。錯誤包(errors package)可以允許我們添加返回錯誤的上下文和堆棧追蹤而解決該問題。

另一個問題是我們可能會忘記處理報錯。諸如 errcheck 和 megacheck 等靜態分析工具可以避免出現這些失誤。雖然這些解決方案十分有效,但可能并不是那么正確的方法。

缺點 3:軟件包管理

Go 語言的軟件包管理絕對不是***的。默認情況下,它沒有辦法制定特定版本的依賴庫,也無法創建可復寫的 builds。相比之下 Python、Node 和 Ruby 都有更好的軟件包管理系統。然而通過正確的工具,Go 語言的軟件包管理也可以表現得不錯。

我們可以使用 Dep 來管理依賴項,它也能指定特定的軟件包版本。除此之外,我們還可以使用一個名為 VirtualGo 的開源工具,它能輕松地管理 Go 語言編寫的多個項目。

[[206818]]

Python vs Go

我們實施的一個有趣實驗是用 Python 寫排名 feed,然后用 Go 改寫。看下面這種排序方法的示例:

  1.    "functions": { 
  2.        "simple_gauss": { 
  3.            "base": "decay_gauss", 
  4.            "scale": "5d", 
  5.            "offset": "1d", 
  6.            "decay": "0.3" 
  7.        }, 
  8.        "popularity_gauss": { 
  9.            "base": "decay_gauss", 
  10.            "scale": "100", 
  11.            "offset": "5", 
  12.            "decay": "0.5" 
  13.        }  
  14.    },  
  15.    "defaults": { 
  16.        "popularity": 1  
  17.    },  
  18.    "score": "simple_gauss(time)*popularity"} 

Python 和 Go 代碼都需要以下要求從而支持上面的排序方法:

  1. 解析得分的表達。在此示例中,我們想要把 simple_gauss(time)*popularity 字符串轉變為一種函數,能夠把 activity 作為輸入然后給出得分作為輸出。
  2. 在 JSON config 上創建部分函數。例如,我們想要「simple_gauss」調用「decay_gauss」,且帶有的鍵值對為"scale": "5d"、"offset": "1d"、"decay": "0.3"。
  3. 解析「defaults」配置,便于某個領域沒有明確定義的情況下有所反饋。
  4. 從 step1 開始使用函數,為 feed 中的所有 activity 打分。

開發 Python 版本排序代碼大約需要 3 天,包括寫代碼、測試和建立文檔。接下來,我么花費大約 2 周的時間優化代碼。其中一個優化是把得分表達 simple_gauss(time)*popularity 轉譯進一個抽象語法樹。我們也實現了 caching logic,之后會預先計算每次的得分。

相比之下,開發 Go 版本的代碼需要 4 天,但之后不需要更多的優化。所以雖然最初的開發上 Python 更快,但 Go 最終需要的工作量更少。此外,Go 代碼要比高度優化的 python 代碼快了 40 多倍。

以上只是我們轉向 Go 所體驗到的一種好處。當然,也不能這么做比較:

  • 該排序代碼是我用 Go 寫的***個項目;
  • Go 代碼是在 Python 代碼之后寫的,所以提前理解了該案例;
  • Go 的表達解析庫質量優越。

Elixir vs Go

我們評估的另一種語言是 Elixir。Elixir 建立在 Erlang 虛擬機上。這是一種迷人的語言,我們之所以想到它是因為我們組員中有一個在 Erlang 上非常有經驗。

在使用案例中,我們觀察到 Go 的原始性能更好。Go 和 Elixir 都能很好地處理數千條并行需求,然而,如果是單獨的要求,Go 實際上更快。相對于 Elixir,我們選擇 Go 的另一個原因是生態系統。在我們需求的組件上,Go 的庫更為成熟。在很多案例中,Elixir 庫不適合產品使用。同時,也很難找到/訓練同樣使用 Elixir 的開發者。

結論

Go 是一種非常高效的語言,高度支持并發性。同時,它也像 C++和 Java 一樣快。雖然相比于 Python 和 Ruby,使用 Go 建立東西需要更多的時間,但在后續的代碼優化上可以節省大量時間。在 Stream,我們有個小型開發團隊為 2 億終端用戶提供 feed 流。對新手開發者而言,Go 結合了強大的生態系統、易于上手,也有超快的表現、高度支持并發性,富有成效的編程環境使它成為了一種好的選擇。Stream 仍舊使用 Python 做個性化 feed,但所有性能密集型的代碼將會用 Go 來編寫。

原文:https://getstream.io/blog/switched-python-go/

【本文是51CTO專欄機構“機器之心”的原創譯文,微信公眾號“機器之心( id: almosthuman2014)”】

 

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO.com
相關推薦

2017-08-28 21:50:09

大數據PythonGo語言

2009-08-26 16:17:10

選華為認證放棄思科

2011-07-21 11:11:10

Scrum

2010-11-19 15:59:51

IT跳槽

2013-02-25 08:59:31

蘋果App Store應用商店

2010-09-13 10:31:29

CSS布局

2013-01-23 10:58:04

2010-05-13 11:36:41

MySQL數據庫

2016-10-17 09:47:21

2014-10-15 11:21:01

HTMLCSS

2015-03-09 09:25:04

2010-05-24 09:09:37

2013-01-15 12:40:21

黑莓10BB10智能手機

2020-02-09 10:11:10

物聯網大數據傳感器

2013-07-17 17:21:49

避免代碼注釋移動開發移動互聯網

2009-07-16 16:56:28

Java

2022-03-15 12:34:07

Nitrux OSLinux 發行版Linux

2014-07-11 13:56:16

2013-09-25 09:58:33

必應

2013-07-16 10:49:11

代碼注釋
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91在线视频免费观看 | 日韩三级免费网站 | 在线不卡一区 | 夜夜艹天天干 | 久久精品一 | 国产亚洲精品精品国产亚洲综合 | 亚洲成人毛片 | 中文字幕一区二区三区四区五区 | 日韩精品一区二区三区久久 | 精品久久久久久亚洲精品 | 亚洲精品一区二三区不卡 | 欧美成人h版在线观看 | 91色视频在线观看 | 国产成人精品一区二区三 | 手机av在线 | 日韩高清一区 | 精品一区二区av | 色播视频在线观看 | 久久一区二区三区四区五区 | 亚洲一二三在线观看 | 日本一卡精品视频免费 | 超碰97免费 | 欧美在线视频免费 | 欧美日韩午夜精品 | 欧洲视频一区二区 | 日韩激情视频一区 | 精品av | 麻豆av在线免费观看 | 日韩在线免费播放 | 久久久久无码国产精品一区 | 狠狠干影院| 一区二区国产精品 | 成人精品鲁一区一区二区 | 青青操91 | 亚洲激情第一页 | 中文字幕第5页 | 精品乱码一区二区 | 香蕉一区| 国产精品久久久久一区二区三区 | 午夜精品久久久久久久星辰影院 | 中文精品一区二区 |