+0和不+0的性能差异
前几日,有群友转发了某位技术大佬的weibo。并在群里询问如下两个函数哪个执行的速度比较快(weibo内容)。
func g(n int, ch chan<- int) {r := 0for i := 0; i < n; i++ {r += i}ch <- r + 0
}func f(n int, ch chan<- int) {r := 0for i := 0; i < n; i++ {r += i}ch <- r
}
很显然,g函数中ch <- r + 0 比 f函数中 ch <- r 多了一个+0
g、f的for循环都执行了n次,对r进行更新
那到底哪个快呢?我们搞了一组Benchmark测试
环境如下:
go version: 1.20
go os: windows
go arch: arm64
代码如下:
package mainimport "testing"func BenchmarkG(b *testing.B) {ch := make(chan int)N := 100000for i := 0; i < b.N; i++ {go g(N, ch)}
}func BenchmarkF(b *testing.B) {ch := make(chan int)N := 100000for i := 0; i < b.N; i++ {go f(N, ch)}
}
为了显现出性能差异,我们直接将g、f两个函数中for循环次数 N 设定为100000(十万次)。
执行结果如下
从结果可以看出:
g函数在单位时间,总共执行了167175次,每次耗时7148ns
f函数在单位时间,总共执行了71856次,每次耗时23909ns
很显然,g函数的执行效率更胜一筹
那为什么会产生这样的结果呢?
话不多说,直接上大招
使用:go tool compile -S ./main.go > dump.txt 将目标go文件的汇编写入dump.txt
下面截取了g函数的主要汇编代码
main.g STEXT size=112 args=0x10 locals=0x28 funcid=0x0 align=0x00x0000 00000 (main.go:11) TEXT main.g(SB), ABIInternal, $48-16...0x0018 00024 (main.go:11) MOVD ZR, R20x001c 00028 (main.go:11) MOVD ZR, R30x0020 00032 (main.go:13) JMP 480x0024 00036 (main.go:13) ADD $1, R2, R40x0028 00040 (main.go:14) ADD R2, R3, R30x002c 00044 (main.go:13) MOVD R4, R20x0030 00048 (main.go:13) CMP R2, R00x0034 00052 (main.go:13) BGT 360x0038 00056 (main.go:16) MOVD R3, main..autotmp_4-8(SP)0x003c 00060 (main.go:16) MOVD R1, R00x0040 00064 (main.go:16) MOVD $main..autotmp_4-8(SP), R10x0044 00068 (main.go:16) PCDATA $1, $10x0044 00068 (main.go:16) CALL runtime.chansend1(SB)0x0048 00072 (main.go:17) LDP -8(RSP), (R29, R30)0x004c 00076 (main.go:17) ADD $48, RSP0x0050 00080 (main.go:17) RET (R30)
下面截取了f函数的主要汇编代码
main.f STEXT size=112 args=0x10 locals=0x28 funcid=0x0 align=0x00x0000 00000 (main.go:3) TEXT main.f(SB), ABIInternal, $48-16...0x0018 00024 (main.go:4) MOVD ZR, main.r-8(SP)0x001c 00028 (main.go:4) MOVD ZR, R20x0020 00032 (main.go:5) JMP 520x0024 00036 (main.go:6) MOVD main.r-8(SP), R30x0028 00040 (main.go:6) ADD R2, R3, R30x002c 00044 (main.go:6) MOVD R3, main.r-8(SP)0x0030 00048 (main.go:5) ADD $1, R2, R20x0034 00052 (main.go:5) CMP R2, R00x0038 00056 (main.go:5) BGT 360x003c 00060 (main.go:8) MOVD R1, R00x0040 00064 (main.go:8) MOVD $main.r-8(SP), R10x0044 00068 (main.go:8) PCDATA $1, $10x0044 00068 (main.go:8) CALL runtime.chansend1(SB)0x0048 00072 (main.go:9) LDP -8(RSP), (R29, R30)0x004c 00076 (main.go:9) ADD $48, RSP0x0050 00080 (main.go:9) RET (R30)
对比一下
不难看出,g函数在循环结构中,只使用了R0、R2、R3、R4寄存器。
f函数在循环结构中,使用了R0、R2、R3寄存器,并在单次循环内,操作了两次栈内存
0x0024 00036 (main.go:6) MOVD main.r-8(SP), R3
将main.r-8(SP)栈内存对应的内容,加载进R3寄存器
0x002c 00044 (main.go:6) MOVD R3, main.r-8(SP)
将R3寄存器的内容写入,main.r-8(SP)栈内存
因为CPU读写内存的速度远低于读写寄存器的速度,所以在大样本量的数据驱动下,g函数的执行速度要远快于f函数的执行速度。
至于为什么出现该性能差异,究其根本,是Go编译器、优化器、对源码编译导致的,也就是编译器的黑魔法使然。
相关文章:
+0和不+0的性能差异
前几日,有群友转发了某位技术大佬的weibo。并在群里询问如下两个函数哪个执行的速度比较快(weibo内容)。 func g(n int, ch chan<- int) {r : 0for i : 0; i < n; i {r i}ch <- r 0 }func f(n int, ch chan<- int) {r : 0for …...
美颜技术讲解:视频美颜SDK的开发与集成
如今,美颜技术的应用愈发成为吸引用户的一项重要功能。本文将深入探讨视频美颜SDK的开发与集成,揭示其背后的技术原理和实现步骤。 一、美颜技术的背后 美颜技术并非仅仅是简单的滤镜效果,而是一项涉及复杂图像处理和算法的技术。在视频美颜…...
期末数组函数加强练习
前言:由于时间问题,部分题解取自网友,但都是做过的好题。 对于有些用c实现的题目,可以转化成c实现,cin看成c的读入,可以用scanf,输出cout看作printf,endl即换行符 开胃菜ÿ…...
如何下载B站视频?我来教你B站视频下载方法
如何下载B站视频?B站作为一个巨大的宝藏库,日常可以拿它作为娱乐工具,刷一些有趣新奇的短视频。也可以把它作为一款成长学习工具,具有丰富的公开课、纪录片内容。 对于较短的视频来说,花费几分钟时间看一下就结束了&am…...
AcWing 3709:单链表节点交换 ← 四川大学考研机试题
【题目来源】 https://www.acwing.com/problem/content/3712/【题目描述】 输入一个单链表,依次交换前2个数,第3、4个数,第5、6个数,…,以此类推,直到操作完整个链表。 如果链表长度是奇数,则最…...
RocketMQ源码 Broker-ConsumerFilterManager 消费者数据过滤管理组件源码分析
前言 ConsumerFilterManager 继承了ConfigManager配置管理组件,拥有将内存数据持久化到磁盘文件consumerFilter.json的能力。它主要负责,对在消费者拉取消息时,进行消息数据过滤,且只针对使用表达式过滤的消费者有效。 源码版本&…...
数据挖掘-07-航空公司客户价值分析(包括数据和代码)
文章目录 0. 数据代码下载1. 背景与挖掘目标2. 导入相关库,加载数据2.1客户基本信息分布a. 绘制会员性别比例饼图b. 绘制会员各级别人数条形图c. 绘制年龄分布图 2.2 客户乘机信息分布分析a. 绘制客户飞行次数箱线图b. 绘制客户总飞行公里数箱线图 2.3 客户积分信息…...
浏览器 css 默认的字体图表
以下是一些常见的浏览器(PC端)中网站 CSS 默认字体及其对应的字体系列(font family): 浏览器默认字体字体系列(font family)ChromeArial, sans-serif“Arial”, “Helvetica Neue”, Helvetica…...
JAVA:注册表窗口的实现
目录 题目要求: 思路大意: 窗体的实现: 窗口A: 窗口B: 窗体之间的构思: 关键代码的实现: 窗口A: 封装列表: 窗口B: 题目要求: 使用…...
Liunx Centos 防火墙操作
liunx centos 防火墙 查看防火墙状态 systemctl status firewalld查看已经开放的端口 firewall-cmd --list-ports添加端口3306 firewall-cmd --zonepublic --add-port3306/tcp --permanent重启防火墙 firewall-cmd --reload数据库开放账号可以外网登陆 mysql -u root -p …...
VirtualBox 和 Vagrant 快速安装 Centos7 报错
VirtualBox 和 Vagrant 快速安装 Centos7 报错 今天尝试用 VirtualBox 和 Vagrant 快速安装 Centos7,BUG 多多! 1)下载 6.1.26 版本 VirtualBox,Windows11 不兼容???什么鬼? 解决…...
使用Python进行数学四则运算
当我们讨论到Python中的计算问题时,我们必然涉及到加法运算符()、减法运算符(-)、乘法运算符(*)以及除法运算符(/)这四大常见的算术运算。下面,我将为您展示如…...
成都工业学院2021级操作系统专周课程设计FCFS,SSTF,SCAN,LOOK算法的实现
运行环境 操作系统:Windows 11 家庭版 运行软件:CLion 2023.2.2 源代码文件 #include <iostream> #include <vector> #include <algorithm> #include <random> using namespace std;// 生成随机数 int generateRandomNumber…...
【51单片机系列】矩阵按键扩展实验
本文对矩阵按键的一个扩展,利用矩阵按键和动态数码管设计一个简易计算器。代码参考:https://blog.csdn.net/weixin_47060099/article/details/106664393 实现功能:使用矩阵按键,实现一个简易计算器,将计算数据及计算结…...
大数据云计算——Docker环境下部署Hadoop集群及运行集群案列
大数据云计算——Docker环境下部署Hadoop集群及运行集群案列 本文着重介绍了在Docker环境下部署Hadoop集群以及实际案例中的集群运行。首先,文章详细解释了Hadoop的基本概念和其在大数据处理中的重要性,以及为何选择在Docker环境下部署Hadoop集群。接着&…...
计算机网络链路层(期末、考研)
计算机网络总复习链接🔗 目录 组帧差错控制检错编码纠错编码 流量控制与可靠传输机制流量控制、可靠传输与滑动窗口机制单帧窗口与停止-等待协议多帧滑动窗口与后退N帧协议(GBN)多帧滑动窗口与选择重传协议 介质访问控制信道划分介质访问控制…...
洛谷 P8794 [蓝桥杯 2022 国 A] 环境治理
文章目录 [蓝桥杯 2022 国 A] 环境治理题目链接题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路解析CODE给点思考 [蓝桥杯 2022 国 A] 环境治理 题目链接 https://www.luogu.com.cn/problem/P8794 题目描述 LQ 国拥有 n n n 个城市,从 0 0 …...
力扣面试150题 | 买卖股票的最佳时期
力扣面试150题 | 买卖股票的最佳时期 题目描述解题思路代码实现 题目描述 121.买卖股票的最佳时期 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票,并选择在 未来的某一…...
uniapp 之 图片 视频 文件上传
<view class"" style"padding: 24rpx 0"><text>相关资料 <text class"fs-26 color-666">(图片、视频、文档不超过9个)</text> </text><view class"flex align-center" style&…...
MIT线性代数笔记-第28讲-正定矩阵,最小值
目录 28.正定矩阵,最小值打赏 28.正定矩阵,最小值 由第 26 26 26讲的末尾可知在矩阵为实对称矩阵时,正定矩阵有以下四种判定方法(都是充要条件): 所有特征值都为正左上角所有 k k k阶子矩阵行列式都为正&…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Python 包管理器 uv 介绍
Python 包管理器 uv 全面介绍 uv 是由 Astral(热门工具 Ruff 的开发者)推出的下一代高性能 Python 包管理器和构建工具,用 Rust 编写。它旨在解决传统工具(如 pip、virtualenv、pip-tools)的性能瓶颈,同时…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
