golang 接口动态派发性能问题
测试代码
package main
type Duck interface {
Quack()
}
type Cat struct {
Name string
}
//go:noinline
func (c Cat) Quack() {
println(c.Name + " meow")
}
func main() {
var c Duck = Cat{Name: "draven"}
c.Quack()
}
指针类型测试用例
func BenchmarkDirectCall(b *testing.B) {
c := &Cat{Name: "draven"}
for n := 0; n < b.N; n++ {
// MOVQ AX, "".c+24(SP)
// MOVQ AX, (SP)
// CALL "".(*Cat).Quack(SB)
c.Quack()
}
}
func BenchmarkDynamicDispatch(b *testing.B) {
c := Duck(&Cat{Name: "draven"})
for n := 0; n < b.N; n++ {
// MOVQ "".d+56(SP), AX
// MOVQ 24(AX), AX
// MOVQ "".d+64(SP), CX
// MOVQ CX, (SP)
// CALL AX
c.Quack()
}
}
结构体类型测试用例
func BenchmarkDirectCall(b *testing.B) {
c := Cat{Name: "draven"}
for n := 0; n < b.N; n++ {
// MOVQ AX, (SP)
// MOVQ $6, 8(SP)
// CALL "".Cat.Quack(SB)
c.Quack()
}
}
func BenchmarkDynamicDispatch(b *testing.B) {
c := Duck(Cat{Name: "draven"})
for n := 0; n < b.N; n++ {
// MOVQ 16(SP), AX
// MOVQ 24(SP), CX
// MOVQ AX, "".d+32(SP)
// MOVQ CX, "".d+40(SP)
// MOVQ "".d+32(SP), AX
// MOVQ 24(AX), AX
// MOVQ "".d+40(SP), CX
// MOVQ CX, (SP)
// CALL AX
c.Quack()
}
}
可以很明显得到如下性能对比图
| 直接调用 | 动态派发 | |
|---|---|---|
| 指针 | ~3.03ns | ~3.58ns |
| 结构体 | ~3.09ns | ~6.98ns |
可以很明显看到使用结构体会带来巨大的性能差异。
在实际项目中如果对这方面有很大的性能需求可以去优化一下。
参考:https://draveness.me/golang/docs/part2-foundation/ch04-basic/golang-interface/#基准测试
golang 接口动态派发性能问题的更多相关文章
- 【Golang 接口自动化06】微信支付md5签名计算及其优化
前言 可能看过我博客的朋友知道我主要是做的支付这一块的测试工作.而我们都知道现在比较流行的支付方式就是微信支付和支付宝支付,当然最近在使用低手续费大力推广的京东金融(已改名为京东数科)以后也可能站到第 ...
- Golang 接口与反射知识要点
目录 Golang 接口与反射知识要点 1. 接口类型变量 2. 类型断言 3. 鸭子类型 4. 反射机制 5. reflect 包 TypeOf().ValueOf() Type().Kind() ...
- Golang 接口
1 接口是什么 Golang中没有像Python.Java拥有类和对象的概念,其封装对象或说明对象是通过接口来实现的.比如谁能够实现什么样的功能,便能够将其抽象化封装. 接口定义了一组方法(抽象方法集 ...
- swift protocol 见证容器 虚函数表 与 动态派发
一.测试代码: //protocol DiceGameDelegate: AnyObject { //} // //@objc protocol OcProtocol{ // @objc fun ...
- swift class的动态派发
一.测试代码 class BaseCallClass{ func NormalCall(){} @objc func OcCall(){} @objc dynamic func OcDynamicCa ...
- Swift 静态派发和动态派发
前言 方法是 Swift 中的一个重要概念,方法允许你把需要复用的代码封装进方法中,这样当你调用方法时,实际上你的想法是执行方法中的那些代码,方法的出现极大的提高了方法的复用性. Swift 工程的环 ...
- swift static与class修饰符:static不参与动态派发
static与class 都有类型成员的含义:相对于实例成员: static的另一个意思是静态派发:所以不能被继承. 要使用动态派发和继承的机制必须使用class继承. static的其它常见含义: ...
- 【Golang 接口自动化00】为什么要用Golang做自动化?
为什么使用Golang做自动化 顺应公司的趋势学习了Golang之后,因为没有开发那么多的时间和项目来实践,怕步此前学习Java缺少练习遗忘殆尽的后尘,决定利用工作之余的时间把此前用Python的写的 ...
- Mybatis学习系列(四)Mapper接口动态代理
实现原理及规范 Mapper接口动态代理的方式需要手动编写Mapper接口,Mybatis框架将根据接口定义创建接口的动态代理对象,代理对象的方法体实现Mapper接口中定义的方法. 使用Mapper ...
- swift派发机制的核心是确定一个函数能否进入动态派发列表
swift派发机制的核心是确定一个函数能否进入动态派发列表
随机推荐
- SpringBoot集成日志
1.日志工厂 如果一个数据库,出现了异常,我们需要排错,日志就是最好的助手! 曾经:sout.debug 现在:日志工厂 在Mybatis中具体使用那一个日志实现,在设置设定 STDOUT_LOGGI ...
- Unity-PC 端调用SpVoice语音 (文字转语音)
第一步引用文件 在VS当中 点击项目->添加引用-> 搜索Microsoft Speech Objecet Library 然后选中前面的白色方块点击确定就行了 插入之后 你的引用库中会多 ...
- 优先队列的基本实现【数据结构与算法—TypeScript 实现】
笔记整理自 coderwhy 『TypeScript 高阶数据结构与算法』课程 特性 效率比普通队列高 每个出队元素拥有最高优先级 可以用 数组.链表 等数据结构实现,但是 堆结构 是最常用的实现方式 ...
- WAF 原理入门
WAF 入门 WAF 功能 WAF 全称叫 Web Application Firewall,和传统防火墙的区别是,它是工作在应用层的防火墙,主要对 web 请求/响应进行防护.那么 WAF 有什么功 ...
- Godot UI线程,Task异步和消息弹窗通知
目录 前言 线程安全 全局消息IOC注入 消息窗口搭建 最简单的消息提示 简单使用 仿Element UI ElementUI 效果 简单的Label样式 如何快速加载多个相同节点 修改一下,IOC按 ...
- WP/C#实现图像滤镜优化方案:打造炫目视觉体验!
原因:我之所以想做这个项目,是因为在之前查找关于C#/WPF相关资料时,我发现讲解图像滤镜的资源非常稀缺.此外,我注意到许多现有的开源库主要基于CPU进行图像渲染.这种方式在处理大量图像时,会导致CP ...
- WPF开发随笔收录-操作注册表
一.前言 在windows平台软件开发过程中,注册表的操作是经常会遇到的一个场景.今天记录一下在操作注册表时遇到的一些坑: 二.正文 1.操作注册表,于是直接从网上找了一段代码来用 /// <s ...
- 第 7章 Python 爬虫框架 Scrapy(上)
第 7章 Python 爬虫框架 Scrapy(上) 编写爬虫可以看成行军打仗,基本的角色有两个:士兵和将军,士兵冲锋陷阵,而将军更多地是调兵遣将.框架就像一个将军,里面包含了爬虫的全部流程.异常处理 ...
- 新零售标杆 SKG 全面拥抱 Serverless,实现敏捷交付
简介: SKG CTO 王焱:以前需要 60 个人干的活,用 SAE 和大禹后 15 个人就可以! 作者:陈列昂.昕辰.龙琛.黛忻 项目背景 SKG 公司是一家专注于高端健康产品的研发.设计与制造 ...
- PolarDB for PostgreSQL 开源路线图
简介:作者:蔡乐 本文主要分享一下Polar DB for PG的开源路线图,虽然路线图已经拟定,但是作为开源产品,所有参与者都能提出修改意见,包括架构核心特性的技术以及周边生态和工具等,希望大家能 ...