测试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#hg%2Fsrc%2Fpkg%2Fcontainer%2Fvector

可能和我测试用的代码有差别,没仔细对比过,不过应该差不多。

Go语言中interface的实现:http://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中的泛型,参见:泛型编程的困境



目录
相关文章
|
17天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
26 7
|
17天前
|
Go 开发工具
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
17天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
92 71
|
16天前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
100 67
|
19天前
|
Go 索引
go语言for遍历数组或切片
go语言for遍历数组或切片
88 62
|
21天前
|
并行计算 安全 Go
Go语言中的并发编程:掌握goroutines和channels####
本文深入探讨了Go语言中并发编程的核心概念——goroutine和channel。不同于传统的线程模型,Go通过轻量级的goroutine和通信机制channel,实现了高效的并发处理。我们将从基础概念开始,逐步深入到实际应用案例,揭示如何在Go语言中优雅地实现并发控制和数据同步。 ####
|
17天前
|
存储 Go
go语言中映射
go语言中映射
32 11
|
19天前
|
Go
go语言for遍历映射(map)
go语言for遍历映射(map)
29 12
|
18天前
|
Go 索引
go语言使用索引遍历
go语言使用索引遍历
26 9
|
22天前
|
安全 Serverless Go
Go语言中的并发编程:深入理解与实践####
本文旨在为读者提供一个关于Go语言并发编程的全面指南。我们将从并发的基本概念讲起,逐步深入到Go语言特有的goroutine和channel机制,探讨它们如何简化多线程编程的复杂性。通过实例演示和代码分析,本文将揭示Go语言在处理并发任务时的优势,以及如何在实际项目中高效利用这些特性来提升性能和响应速度。无论你是Go语言的初学者还是有一定经验的开发者,本文都将为你提供有价值的见解和实用的技巧。 ####
下一篇
DataWorks