閱讀973 返回首頁    go 阿裏雲 go 技術社區[雲棲]


測試Go語言的interface的效率

interface是Go語言中的一大特點,甚至說是靈魂也不為過。

interface應該會在Go程序中大量出現和使用,因為有必要了解和測試下它的效率。


測試思路:

使用vector包,測試原生的IntVector和用interface包裝後的vector的效率。

Go1中去掉了vector包,不過當時我把vector的代碼保留了一份,微笑

在代碼庫裏應該也能找到。我找到了一個版本的:https://code.google.com/p/go/source/browse?name=weekly.2011-08-17

可能和我測試用的代碼有差別,沒仔細對比過,不過應該差不多。

Go語言中interface的實現:https://research.swtch.com/interfaces

據作者說一次函數調用要花5條CPU指令(C++的虛函數是3條)。

下麵是測試代碼:

package main

import (
	"fmt"
	"time"
	. "vector"
//	"vector/vector"
)

const size = 1000000

func testIntVectorPush() {
	v := make(IntVector, size)
	t0 := time.Now()
	for i := 1; i < size; i++ {
		v.Push(i)
	}
	t1 := time.Now()
	fmt.Printf("The testIntVectorPush call took %v to run.\n", t1.Sub(t0))
	v = nil
}

func testIntVectorAt() {
	v := make(IntVector, size)
	t0 := time.Now()
	for j := 0; j < 1000; j++ {
		for i := 1; i < size; i++ {
			v.At(i)
		}
	}
	t1 := time.Now()
	fmt.Printf("The testIntVectorAt call took %v to run.\n", t1.Sub(t0))
	v = nil
}

func testVectorPush() {
	v := make(Vector, size)
	t0 := time.Now()
	for i := 1; i < size; i++ {
		v.Push(i)
	}
	t1 := time.Now()
	fmt.Printf("The testVectorPush call took %v to run.\n", t1.Sub(t0))
	v = nil
}

func testVectorAt() {
	v := make(Vector, size)
	t0 := time.Now()
	for j := 0; j < 1000; j++ {
		for i := 1; i < size; i++ {
			v.At(i)
		}
	}

	t1 := time.Now()
	fmt.Printf("The testVectorAt call took %v to run.\n", t1.Sub(t0))
	v = nil
}

func main() {
	fmt.Println("abc")
	i := 0
	for ; i < size; i++ {
		i += i
	}
	fmt.Println(i)

	testIntVectorPush()
	testIntVectorPush()
	testVectorPush()
	testVectorPush()

	testIntVectorAt()
	testIntVectorAt()
	testVectorAt()
	testVectorAt()

}

測試結果:

The testIntVectorPush call took 19.0011ms to run.
The testIntVectorPush call took 19.0011ms to run.
The testVectorPush call took 64.0037ms to run.
The testVectorPush call took 51.0029ms to run.
The testIntVectorAt call took 1.2920739s to run.
The testIntVectorAt call took 1.2990743s to run.
The testVectorAt call took 2.4831421s to run.
The testVectorAt call took 2.5131438s to run.

明顯地原生的IntVector比用interface包裝過的Vector要快2到3倍。


總結:

Go語言中的interface很靈活,但是也付出了一定的性能代價。

如果是性能關鍵的代碼,可以考慮放棄interface,自己寫原生的代碼。

話說回來,沒有泛型機製,真的比較蛋疼,相當期待Go能支持泛型。

關於Go中的泛型,參見:泛型編程的困境



最後更新:2017-04-02 16:47:50

  上一篇:go Struts2中的異常處理
  下一篇:go 《洛克菲勒留給兒子的38封信》 第一封:起點不決定終點