兩個最多能夠提升千倍效率的Go語言代碼小技巧

http://dawngrp.com/gao-xiao-de-goyu-yan-bian-ma-ji-qiao/

1.不要使用+和fmt.Sprintf操做字符串

+操做字符串很方便,可是真的很慢,在Go語言裏使用+會致使你的程序跑得可能比腳本語言還滿,不相信的能夠本身作個測試,用+操做,迭代十萬次,Python、Javascript都比Go快不少(是不少噢,不是一點點)python

func TestStr(t *testing.T) {
    str := ""
    for i := 0; i < 100000; i++ {
        str += "test"
    }
}

測試結果性能

PASS: TestStr (3.32s)
str=""
for i in range(100000):
    str+="test"

測試結果:測試

~/» time python test.py
0.03s user 0.03s system 81% cpu 0.078 total

做爲靜態語言的Go,竟然在這麼一個段簡單的代碼上執行效率比Python慢了100倍,難以想象吧?不是Go的問題,而是在Go中使用+處理字符串是很消耗性能的,而Python應該是對+操做字符串進行了重載優化。(Javascript +操做字符串也很快)優化

最有效的方式是採用buffer
strBuf := bytes.NewBufferString("")
for i := 0; i < 100000; i++ {
    strBuf.WriteString("test")
}

結果能夠本身測試,會讓你很驚訝spa

有一些須要簡單組合兩個字符串,用Buffer麻煩了點,比較容易讓人想到的就是用fmt.Sprintf()來組合,不少包裏的源碼也是這麼寫的。其實fmt的Sprintf也很是慢,若是沒有複雜的類型轉換輸出的狀況下,使用strings.Join性能會高不少code

func TestStr(t *testing.T) {
    a, b := "Hello", "world"
    for i := 0; i < 1000000; i++ {
        fmt.Sprintf("%s%s", a, b)
        //strings.Join([]string{a, b}, "")
    }
}
PASS: TestStr (0.29s)
func TestStr(t *testing.T) {
    a, b := "Hello", "world"
    for i := 0; i < 1000000; i++ {
        //fmt.Sprintf("%s%s", a, b)
        strings.Join([]string{a, b}, "")
    }
}
PASS: TestStr (0.09s)

從結果來看strings.Join 比用Sprint快4倍左右吧。blog

2.對於固定字段的鍵值對,用臨時Struct,不要用map[string]interface{}

舉個簡單的例子索引

func TestData(t *testing.T) {

    for i := 0; i < 100000000; i++ {
        var a struct {
            Name string
            Age  int
        }
        a.Name = "Hello"
        a.Age = 10
    }
}
PASS: TestData (0.04s)
func TestData2(t *testing.T) {

    for i := 0; i < 100000000; i++ {
        var a = map[string]interface{}{}
        a["Name"] = "Hello"
        a["Age"] = 10
    }
}
PASS: TestData2 (38.30s)

相差上千倍的效率呢!
在可以知道字段的狀況下,用臨時Struct在運行期間不須要動態分配內容,而且不須要像map那樣去檢查索引,因此速度會快很是多。ip

相關文章
相關標籤/搜索