golang type assertion and unsafe.Pointer 性能对比
Posted 惜暮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了golang type assertion and unsafe.Pointer 性能对比相关的知识,希望对你有一定的参考价值。
golang type assertion and unsafe.Pointer 性能对比
最近项目中有这样一个需求背景:有一个存储实体用来做各种指标的counter。这个counter的实现需要能够在以后被别的实现替换。结构自然是这样:
type XXXObj struct
startTime uint64
counter interface//暂时用interface表示,表示该对象类似于泛型的存在
为了避免对象拷贝,所以其实这里存储的一定会是一个指针。所以这里还有一个可选方案:unsafe.Pointer.
最初的设计,这一块更像泛型的一种思想,所以很自然的使用了interface。
但是上层拿到这个 interface 之后肯定要做类型断言,转成实际的counter对象指针,然后执行实际的统计操作。这一块是一个非常高频的调用。所以performance是非常重要的点。
所以想测试一下:直接调用、类型断言,unsafe.Pointer转换三种方式的性能对比。下面是一个test 的benchmark。这里申明一下这里仅仅针对泛型对象是指针的场景:
package assertion
import (
"testing"
"unsafe"
)
type Student struct
Name string
Age int
Class string
Score int
func DirectInvoke(s *Student)
s.Name = "Jerry"
s.Age = 18
s.Class = "20005"
s.Score = 100
func PointerInvoke(p unsafe.Pointer)
s := (*Student)(p)
s.Name = "Jerry"
s.Age = 18
s.Class = "20005"
s.Score = 100
func InterfaceInvoke(i interface)
s := i.(*Student)
s.Name = "Jerry"
s.Age = 18
s.Class = "20005"
s.Score = 100
func BenchmarkAssertDirectInvoke(b *testing.B)
s := new(Student)
b.ResetTimer()
for i := 0; i < b.N; i++
DirectInvoke(s)
_ = s
func BenchmarkAssertPointerInvoke(b *testing.B)
s := new(Student)
b.ResetTimer()
for i := 0; i < b.N; i++
PointerInvoke(unsafe.Pointer(s))
_ = s
func BenchmarkAssertInterfaceInvoke(b *testing.B)
s := new(Student)
b.ResetTimer()
for i := 0; i < b.N; i++
InterfaceInvoke(s)
_ = s
三种场景跑出来的结果是:
// 环境:mac pro 2015, 13-in, 4核8G内存
$go test -bench='BenchmarkAssert*' -benchmem
goos: darwin
goarch: amd64
pkg: study_golang/study/basic/assertion
BenchmarkAssertDirectInvoke-4 1000000000 0.328 ns/op 0 B/op 0 allocs/op
BenchmarkAssertPointerInvoke-4 1000000000 0.332 ns/op 0 B/op 0 allocs/op
BenchmarkAssertInterfaceInvoke-4 559252803 2.03 ns/op 0 B/op 0 allocs/op
PASS
ok study_golang/study/basic/assertion 2.095s
从benchmark结果来看,直接调用和使用指针的性能基本是一样的。但是使用interface再做 type assertion 的方式就性能相比就差很多了。但是实际指令执行的速度都是在ns 级别,所以速度似乎又都能接受。
我们应该关注的应该是,为什么 interface 的方式和type assertion速度会差这么多?根据我的了解,这里应该与 interface的拆箱,装箱,以及类型断言的实际原理有关。
以上是关于golang type assertion and unsafe.Pointer 性能对比的主要内容,如果未能解决你的问题,请参考以下文章
golang --Converting and Checking Types