程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

簡單說說Python與Go的區別

編輯:Python

背景

工作中的主力語言是Python,今年要搞性能測試的工具,由於GIL鎖的原因,Python的性能實在是慘淡,需要學一門性能高的語言來生成性能測試的壓力端。因此我把目光放在了現在的新秀Go。經過一段時間的學習,也寫了一個小工具,記一下這兩個語言的區別。

需求

工具是一個小爬蟲,用來爬某網站的某個產品的迭代記錄,實現邏輯就是運行腳本後,使用者從命令行輸入某些元素(產品ID等)後,腳本導出一個Excel文件出來。

最初的版本是用Python寫的,30行代碼不到就搞定了。這次用Go重寫,代碼量在110行左右。

接受輸入

第一步就是接受命令行的輸入內容,工具要給非技術人員用的,弄一個CLI不太合適,要的效果就是一行一行的輸入內容,用Python實現起來非常容易,像這樣:

app_id = raw_input('請輸入app_id: ')
app_analysis = raw_input('請輸入analysis: ')

執行後就是一行一行的往下走,但是用Go就有點蛋疼了,完整的代碼如下:

func getPara() (string, string) {
var i = 0
var appId, analysis string
fmt.Print("請輸入appId:")
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
text := scanner.Text()
if i == 0 {
appId = text
fmt.Print("請輸入analysis:")
} else if i == 1 {
analysis = text
fmt.Print("程序初始化數據完畢。。。。請按任意鍵繼續")
} else {
break
}
i++
}
return appId, analysis
}

Go要實現CLI很方便,但是涉及到這種一行一行的輸入,要一直監聽Scan(),所以就有了上面蛋疼的循環處理,而且在必須要先打印信息,再來監聽內容,總體的寫的過程很惡心,也許是沒有找到更好的方法吧,實在是太逆天了。

發送請求

在發送請求方便,兩種語言倒是差別不太大,至少我寫的Get請求是這樣的。

Python
params = {
"analysis": app_analysis,
"appid": app_id,
"country": 'cn'
}
r = requests.get(url, params)
Go
q := req.URL.Query()
q.Add("appid", appId)
q.Add("analysis", analysis)
q.Add("country", "cn")
req.URL.RawQuery = q.Encode()
var resp *http.Response
resp, _ = http.DefaultClient.Do(req)

返回結果處理

在返回結果的處理上,Python的處理方式簡直是太友好了,直接調用json就處理了。

result = r.json()

但是Go就有點蛋疼了,由於是靜態語言,所以解包數據的時候需要先定義數據格式,比如返回的內容必須要先做如下的結構定義:

type ResultInfo struct {
Code int
Msg string
Version []VersionInfo
}
type VersionInfo struct {
Version string `json:"version"`
ReleaseTime string `json:"release_time"`
ReleaseNote string `json:"release_note"`
AppName string `json:"app_name"`
SubTitle string `json:"subtitle"`
}

第一個ResultInfo是返回的數據,其中的Version也是一個數組對象,所以還要再定義一個數組對象,這樣才能調用方法來解包處理。

body, _ := ioutil.ReadAll(resp.Body)
var rst = ResultInfo{}
if err := json.Unmarshal(body, &rst); err != nil {
fmt.Println(err)
}

寫數據到Excel

這部分調用的都是第三方庫,所以沒什麼可比性,代碼的實現完全依賴於第三方包。

無所不在的err != nil

Go的異常捕獲機制跟Python或者Java都不一樣,Python的異常捕獲使用的是try,except來包裹代碼塊,而Go用的是一個error對象,所以所有的Go代碼都會充斥著大量的

if err != nil {
return nil, err
}

這種鬼東西,這種異常機制在閱讀代碼的時候,非常惡心,極大的影響了閱讀體驗。

吐槽完後

基本上從書寫代碼的過程來看,Python的編碼效率比Go高出了很多很多,Go號稱語法靈活,可以極大的提高編碼效率,實際上並沒有,受限於靜態語言,相比於Python這種動態語言來說,編碼效率的差距還是非常大的。只能說比其他靜態語言編碼效率高。

但是!!!

Go的效率比Python高了太多。舉個例子,有一個計算斐波那契數的算法,Go的實現如下:

func main() {
const n = 40
starttime := time.Now()
fibN := fib(n)
endtime := time.Now()
cost_time := endtime.Sub(starttime)
fmt.Println(cost_time)
fmt.Printf("\rFibonacci(%d) = %d\n", n, fibN)
}
func fib(x int) int {
if x < 2 {
return x
}
return fib(x-1) + fib(x-2)
}

很簡單的一個遞歸,當N為40的時候,Go花了大概1秒左右的時間,執行結果如下:

876.838ms(消耗時間) Fibonacci(40) = 102334155

我們換成Python

def fib(x):
if x<2:
return x
return fib(x-1)+fib(x-2)
if __name__ == '__main__':
import time
begin = time.time()
print fib(40)
end = time.time()
print end-begin

一樣的執行邏輯,執行的結果卻是:

102334155
52.8657081127(消耗時間)

WTF!!! 用Go來處理效率是Python的50倍以上。

還沒完,工具寫完了總是要給人用的吧,Python寫完之後,如果給一個非技術人員使用,那麼。。。

使用者:要怎麼用?
我:你裝一下Python,然後配好環境變量,順便把requests庫和xlwt庫也裝一下。
我:要裝這兩個庫你要先裝一下pip。
使用者:黑人問號臉!!!!!

如果你用Go來寫,打包完發過去就行了

使用者:要怎麼用?
我:你雙擊一下,讓你輸入什麼就輸入什麼

如果使用者是用Windows系統,那也沒問題,

CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build xxx.go

直接打包成exe文件。


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved