测试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中的泛型,参见:泛型编程的困境



目录
相关文章
|
16小时前
|
存储 安全 编译器
go语言中进行不安全的类型操作
【5月更文挑战第10天】Go语言中的`unsafe`包提供了一种不安全但强大的方式来处理类型转换和底层内存操作。包含两个文档用途的类型和八个函数,本文也比较了不同变量和结构体的大小与对齐系数,强调了字段顺序对内存分配的影响。
29 8
go语言中进行不安全的类型操作
|
19小时前
|
Go
配置go语言下载包 - 蓝易云
这个命令会将包下载到你的GOPATH目录下,并自动安装它。
14 1
|
1天前
|
安全 Go 调度
Go语言中的并发编程
Go语言自带了强大的并发编程能力,它的协程机制可以让程序轻松地实现高并发。本文将从并发编程的基础概念出发,介绍Go语言中的协程机制、通道和锁等相关知识点,帮助读者更好地理解并发编程在Go语言中的实践应用。
|
3天前
|
Ubuntu Unix Linux
【GO基础】1. Go语言环境搭建
【GO基础】1. Go语言环境搭建
|
4天前
|
JSON 前端开发 Go
lucky - go 语言实现的快速开发平台
go 语言实现的快速开发平台,自动生成crud代码,前端页面通过json配置,无需编写前端代码。
11 0
|
5天前
|
存储 Java Go
Go 语言切片如何扩容?(全面解析原理和过程)
Go 语言切片如何扩容?(全面解析原理和过程)
14 2
|
5天前
|
负载均衡 Go 调度
使用Go语言构建高性能的Web服务器:协程与Channel的深度解析
在追求高性能Web服务的今天,Go语言以其强大的并发性能和简洁的语法赢得了开发者的青睐。本文将深入探讨Go语言在构建高性能Web服务器方面的应用,特别是协程(goroutine)和通道(channel)这两个核心概念。我们将通过示例代码,展示如何利用协程处理并发请求,并通过通道实现协程间的通信和同步,从而构建出高效、稳定的Web服务器。
|
5天前
|
算法 Go 分布式数据库
构建高可用的分布式数据库集群:使用Go语言与Raft共识算法
随着数据量的爆炸式增长,单一数据库服务器已难以满足高可用性和可扩展性的需求。在本文中,我们将探讨如何使用Go语言结合Raft共识算法来构建一个高可用的分布式数据库集群。我们不仅会介绍Raft算法的基本原理,还会详细阐述如何利用Go语言的并发特性和网络编程能力来实现这一目标。此外,我们还将分析构建过程中可能遇到的挑战和解决方案,为读者提供一个完整的实践指南。
|
5天前
|
消息中间件 Go API
基于Go语言的微服务架构实践
随着云计算和容器化技术的兴起,微服务架构成为了现代软件开发的主流趋势。Go语言,以其高效的性能、简洁的语法和强大的并发处理能力,成为了构建微服务应用的理想选择。本文将探讨基于Go语言的微服务架构实践,包括微服务的设计原则、服务间的通信机制、以及Go语言在微服务架构中的优势和应用案例。
|
5天前
|
安全 测试技术 数据库连接
使用Go语言进行并发编程
【5月更文挑战第15天】Go语言以其简洁语法和强大的并发原语(goroutines、channels)成为并发编程的理想选择。Goroutines是轻量级线程,由Go运行时管理。Channels作为goroutine间的通信机制,确保安全的数据交换。在编写并发程序时,应遵循如通过通信共享内存、使用`sync`包同步、避免全局变量等最佳实践。理解并发与并行的区别,有效管理goroutine生命周期,并编写测试用例以确保代码的正确性,都是成功进行Go语言并发编程的关键。