Go 官方标准编译器中所做的优化
本文是对#102 Go 官方标准编译器中实现的优化集锦汇总[1] 内容的记录与总结.
优化1-4: 字符串和字节切片之间的转化
1.紧跟range关键字的 从字符串到字节切片的转换;
package main
import (
"fmt"
"strings"
"testing"
)
var cs10086 = strings.Repeat("shuang!", 10086)
func main() {
fmt.Println(testing.AllocsPerRun(1, f)) //0
fmt.Println(testing.AllocsPerRun(1, g)) //1
}
func f() {
for range []byte(cs10086) {
}
}
func g() {
bs := []byte(cs10086)
for range bs {
}
}
f没有开辟内存,g开辟了一次内存.
2.映射元素读取索引语法中被用做键值的 从字节切片到字符串的转换;
package main
import (
"bytes"
"fmt"
"testing"
)
var name = bytes.Repeat([]byte{'x'}, 188)
var m = make(map[string]string, 10)
var s = ""
func main() {
fmt.Println(testing.AllocsPerRun(1, f2)) //0
fmt.Println(testing.AllocsPerRun(1, g2)) //1
fmt.Println(testing.AllocsPerRun(1, h2)) //1
}
func f2() {
s = m[string(name)] // 有效
}
func g2() {
key := string(name)
s = m[key] // 无效
}
func h2() {
m[string(name)] = "Golang" // 无效
}
3.字符串比较表达式中被用做比较值的 从字节切片到字符串的转换
package main
import (
"fmt"
"testing"
)
var x = []byte{1023: 'x'}
var y = []byte{1023: 'y'}
var b bool
func main() {
fmt.Println(testing.AllocsPerRun(1, f3)) //0
fmt.Println(testing.AllocsPerRun(1, g3)) //2
}
func f3() {
b = string(x) != string(y)
}
func g3() {
sx, sy := string(x), string(y)
b = sx == sy
}
4.含 非空字符串常量 的字符串衔接表达式中的 从字节切片到字符串的转换
package main
import (
"fmt"
"testing"
)
var p = []byte{1023: 'p'}
var q = []byte{1023: 'q'}
var str string
func main() {
fmt.Println(testing.AllocsPerRun(1, f4)) //1
fmt.Println(testing.AllocsPerRun(1, g4)) //3
}
func f4() {
str = ("-" + string(p) + string(q))[1:]
}
func g4() {
str = string(p) + string(q)
}
5.[]rune(aString)转换的时间和空间复杂度都是O(n),但len([]rune(aString))中的此转换 不需要开辟内存
Go 1.12引入
package main
import (
"fmt"
"strings"
"testing"
)
var shuang = strings.Repeat("shuang!", 10086)
func main() {
fmt.Println(testing.AllocsPerRun(1, f5)) //0
fmt.Println(testing.AllocsPerRun(1, g5)) //1
}
func f5() {
_ = len([]rune(shuang))
}
func g5() {
_ = len([]byte(shuang)) //未对len([]byte(aString))做优化
}
6.字符串衔接表达式只需开辟一次内存,无论需要衔接多少个字符串
package main
import (
"fmt"
"testing"
)
var h, i, j, k = "Hello", "World", "Let's", "Go"
var str6 string
func main() {
fmt.Println(testing.AllocsPerRun(1, f6)) //1
fmt.Println(testing.AllocsPerRun(1, g6)) //3
}
func f6() {
str6 = h + i + j + k
}
func g6() {
str6 = h + i
str6 += j
str6 += k
}
7.for i := range anArrayOrSlice{anArrayOrSlice[i]} = zeroElement} 形式 将被优化为一个内部的memclr操作
package main
const N = 1024 * 100
var arr [N]int
func clearArray() {
for i := range arr {
arr[i] = 0
}
}
func clearSlice() {
sli := arr[:]
for i := range sli {
sli[i] = 0
}
}
func clearArrayPtr() {
for i := range &arr {
arr[i] = 0
}
}
benchmark:
package main
import (
"testing"
)
func BenchmarkTest1(b *testing.B) {
for i := 0; i < b.N; i++ {
clearArray()
}
}
func BenchmarkTest2(b *testing.B) {
for i := 0; i < b.N; i++ {
clearSlice()
}
}
func BenchmarkTest3(b *testing.B) { //无效
for i := 0; i < b.N; i++ {
clearArrayPtr()
}
}
执行结果:
goos: darwin
goarch: amd64
pkg: xxxx
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
BenchmarkTest1-8 73000 15309 ns/op
BenchmarkTest2-8 76464 15167 ns/op
BenchmarkTest3-8 40194 30096 ns/op
PASS
ok xxxx 4.213s
8.for k = range m {delete(m,k)}形式 将被优化为一个内部的map清空操作
9.尺寸不大于4个原生字(即int),并且字段数不超过4个的结构体值被视为是小尺寸值
package main
type S1 struct {
a int
}
type S2 struct {
a, b int
}
type S3 struct {
a, b, c int
}
type S4 struct {
a, b, c, d int
}
type S5 struct {
a, b, c, d, e int
}
type S6 struct {
a, b, c, d, e, f int
}
var ss1, ss2, ss3, ss4, ss5, ss6 = make([]S1, 1000), make([]S2, 1000), make([]S3, 1000), make([]S4, 1000), make([]S5, 1000), make([]S6, 1000)
var x1, x2, x3, x4, x5, x6 int
benchmark:
package main
import "testing"
func Benchmark_Range1(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss1 {
x1 = v.a
}
}
}
func Benchmark_Range2(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss2 {
x2 = v.a
}
}
}
func Benchmark_Range3(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss3 {
x3 = v.a
}
}
}
func Benchmark_Range4(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss4 {
x4 = v.a
}
}
}
func Benchmark_Range5(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss5 {
x5 = v.a
}
}
}
func Benchmark_Range6(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, v := range ss6 {
x6 = v.a
}
}
}
执行结果:
goos: darwin
goarch: amd64
pkg: xxxx
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
Benchmark_Range1-8 4759434 248.4 ns/op
Benchmark_Range2-8 3910621 306.0 ns/op
Benchmark_Range3-8 3735921 328.9 ns/op
Benchmark_Range4-8 3677784 325.9 ns/op
Benchmark_Range5-8 814666 1517 ns/op
Benchmark_Range6-8 728656 1568 ns/op
PASS
ok xxxx 8.868s
因为很多一等公民,其底层结构体的元素,都没有超过4个
10.接口值包裹 指针值 比 包裹 其他类型的值 要快
package main
var p, p2 = new([100]int), new([100]int)
var ip interface{}
package main
import "testing"
func Benchmark_PointerAssign(b *testing.B) {
for i := 0; i < b.N; i++ {
p = p2
}
}
func Benchmark_BoxPointer(b *testing.B) {
for i := 0; i < b.N; i++ {
ip = p
}
}
func Benchmark_PointerAssert(b *testing.B) {
for i := 0; i < b.N; i++ {
p = ip.(*[100]int)
}
}
goos: darwin
goarch: amd64
pkg: xxxx
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
Benchmark_PointerAssign-8 1000000000 0.5251 ns/op 0 B/op 0 allocs/op
Benchmark_BoxPointer-8 1000000000 0.5833 ns/op 0 B/op 0 allocs/op
Benchmark_PointerAssert-8 1000000000 0.6418 ns/op 0 B/op 0 allocs/op
PASS
ok xxxx 2.372s
11.接口值包裹 指针值 比 包裹 其他类型的值 要快
Go 1.15新增优化
package main
var x,y = 255,256
var ix,iy interface{}
package main
import "testing"
func Benchmark_x(b *testing.B) {
for i := 0; i < b.N; i++ {
ix = x
}
}
func Benchmark_y(b *testing.B) {
for i := 0; i < b.N; i++ {
iy = y
}
}
goos: darwin
goarch: amd64
pkg: xxxx
cpu: Intel(R) Core(TM) i7-8557U CPU @ 1.70GHz
Benchmark_x-8 565624285 2.033 ns/op 0 B/op 0 allocs/op
Benchmark_y-8 92127024 12.71 ns/op 8 B/op 1 allocs/op
PASS
ok xxxx 2.653s
12.Bounds Check Elimination
参考资料
#102 Go 官方标准编译器中实现的优化集锦汇总: https://www.bilibili.com/video/BV1YZ4y1K7w2
本文由 mdnice 多平台发布
相关文章:
Go 官方标准编译器中所做的优化
本文是对#102 Go 官方标准编译器中实现的优化集锦汇总[1] 内容的记录与总结. 优化1-4: 字符串和字节切片之间的转化 1.紧跟range关键字的 从字符串到字节切片的转换; package mainimport ( "fmt" "strings" "testing")var cs10086 s…...
C语言程序设计——小学生计算机辅助教学系统
题目:小学生计算机辅助教学系统 编写一个程序,帮助小学生学习乘法。然后判断学生输入的答案对错与否,按下列任务要求以循序渐进的方式分别编写对应的程序并调试。 任务1 程序首先随机产生两个1—10之间的正整数,在屏幕上打印出问题…...
SQL自动递增的列恢复至从0开始
在许多数据库管理系统中,当你删除表格中的所有数据时,自动递增的列(也称为自增列、标识列或序列)的计数器通常不会重置为 0。这是出于性能和数据完整性方面的考虑,以避免因删除数据而导致的自增列值冲突。即使你删除了…...
介绍一下CDN
CDN(内容分发网络,Content Delivery Network)是一个由多个服务器组成的分布式网络,它的目的是将内容高效地传送到用户。下面是CDN的工作原理及其主要特点: 内容分发:当用户首次请求某一特定内容时ÿ…...
2023年最新 Github Pages 使用手册
参考:GitHub Pages 快速入门 1、什么是 Github Pages GitHub Pages 是一项静态站点托管服务,它直接从 GitHub 上的仓库获取 HTML、CSS 和 JavaScript 文件,(可选)通过构建过程运行文件,然后发布网站。 可…...
docker 安装 Nginx
1、下载 docker pull nginx:latest 2、本地创建管理目录 mkdir -p /var/docker/nginx/conf mkdir -p /var/docker/nginx/log mkdir -p /var/docker/nginx/html 3、将容器中的相应文件复制到管理目录中 /usr/docker/nginx docker run --name nginx -p 80:80 -d nginxdocke…...
【NLP的python库(01/4) 】: NLTK
一、说明 NLTK是一个复杂的库。自 2009 年以来不断发展,它支持所有经典的 NLP 任务,从标记化、词干提取、词性标记,包括语义索引和依赖关系解析。它还具有一组丰富的附加功能,例如内置语料库,NLP任务的不同模型以及与S…...
Java IDEA Web 项目 1、创建
环境: IEDA 版本:2023.2 JDK:1.8 Tomcat:apache-tomcat-9.0.58 maven:尚未研究 自行完成 IDEA、JDK、Tomcat等安装配置。 创建项目: IDEA -> New Project 选择 Jakarta EE Template:选择…...
leetcode316. 去除重复字母(单调栈 - java)
去除重复字母 题目描述单调栈代码演示进阶优化 上期经典 题目描述 难度 - 中等 leetcode316. 去除重复字母 给你一个字符串 s ,请你去除字符串中重复的字母,使得每个字母只出现一次。需保证 返回结果的字典序最小(要求不能打乱其他字符的相对…...
零散笔记:《Spring实战》Thymeleaf
1、Thymeleaf模板就是增加一些额外元素属性的HTML,这些属性能够指导模板如何渲染request数据。 <p th:test "${message}">placeholder message</p> th我推测是中文的”替换“。 2、th:each,迭代元素集合。 <div th:each &qu…...
WordArt Designer:基于用户驱动与大语言模型的艺术字生成
AIGC推荐 FaceChain人物写真开源项目,支持风格与穿着自定义,登顶github趋势榜首! 前言 本文介绍了一个基于用户驱动,依赖于大型语言模型(LLMs)的艺术字生成框架,WordArt Designer。 该系统包含四个关键模块:LLM引擎、…...
【C进阶】深度剖析数据在内存中的存储
目录 一、数据类型的介绍 1.类型的意义: 2.类型的基本分类 二、整形在内存中的存储 1.原码 反码 补码 2.大小端介绍 3.练习 三、浮点型在内存中的存储 1.一个例子 2.浮点数存储规则 一、数据类型的介绍 前面我们已经学习了基本的内置类型以及他们所占存储…...
TortoiseGit安装
一、安装Git环境 Git-2.42.0-64-bit.exe (访问密码: 1666)https://url48.ctfile.com/f/33868548-924037167-76e273?p1666 二、安装TortoiseGit TortoiseGit-2.14.0.1-64bit.msi (访问密码: 1666)https://url48.ctfile.com/f/33868548-924037173-d395c7?p1666 三、安装T…...
巨人互动|游戏出海游戏出海的趋势如何
随着全球游戏市场的不断扩大和消费者需求的多元化,游戏出海作为游戏行业的重要战略之一,正面临着新的发展趋势。本文小编将讲讲游戏出海的趋势,探讨一下未来游戏出海的发展方向与前景。 巨人互动|游戏出海&2023国内游戏厂商加快“出海”发…...
k8s 安装 istio(二)
3.3 部署服务网格调用链检测工具 Jaeger 部署 Jaeger 服务 kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.16/samples/addons/jaeger.yaml 创建 jaeger-vs.yaml 文件 apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata…...
Postman中参数区别及使用说明
一、Params与Body 二者区别在于请求参数在http协议中位置不一样。Params 它会将参数放入url中以?区分以&拼接Body则是将请求参数放在请求体中 后端接受数据: 二、body中不同格式 2.1 multipart/form-data key - value 格式输入,主要特点是可以上…...
基于python+pyqt的opencv汽车分割系统
目录 一、实现和完整UI视频效果展示 主界面: 识别结果界面: 查看分割处理过程图片界面: 二、原理介绍: 加权灰度化 编辑 二值化 滤波降噪处理 锐化处理 边缘特征提取 图像分割 完整演示视频: 完整代码链…...
游戏设计的主要部分
游戏设计的主要部分 介绍 游戏设计是创建有趣、挑战性和令人满足的游戏体验的过程。它涵盖了许多方面,从概念开发到实际实施,以及最终的游戏测试和优化。游戏设计师需要考虑玩家的情感、技能挑战、故事情节、游戏世界等多个要素,以确保游戏…...
架构师成长之路Redis第二篇|Redis配置文件参数讲解
Redis.conf文件 官网Redis文档链接:Redis官网 官网Redis config配置文件参数讲解:https://redis.io/docs/management/config/ Redis.conf参考模板例子 : https://redis.io/docs/management/config-file/ Redis 可以使用内置的默认配置在没有配置文件的情况下启动,但是仅…...
jsp+servlet+mysql阳光网吧管理系统
项目介绍: 本系统使用jspservletmysql开发的阳光网吧管理系统,纯手工敲打,系统管理员和用户角色,功能如下: 管理员:修改个人信息、修改密码;机房类型管理;机房管理;机位…...
Next.js基础语法
Next.js 目录结构 入口App组件(_app.tsx) _app.tsx是项目的入口组件,主要作用: 可以扩展自定义的布局(Layout)引入全局的样式文件引入Redux状态管理引入主题组件等等全局监听客户端路由的切换 ts.config…...
selenium进阶之web自动化项目框架搭建(Python版)
web自动化项目框架搭建 1、项目结构 web自动化框架的设计,同接口自动化框架一样,采用分层设计。 文件或目录说明common常用模块,常用的一些函数封装testcases用例模块,所有的测试用例test_data用例数据logs日志目录reports报告s…...
qt设计界面
widget.h #ifndef WIDGET_H #define WIDGET_H //防止文件重复包含#include <QWidget> //QWidget类所在的头文件,父类头文件 #include<QIcon> #include<QPushButton> …...
《C和指针》笔记12: 存储类型(自动变量、静态变量和寄存器变量)
文章目录 1. 自动变量(auto)1.1 自动变量的初始化 2. 静态变量(static)2.1 静态变量的初始化 3. 寄存器变量(register) 1. 自动变量(auto) 在代码块内部声明的变量的缺省存储类型是…...
无限计算力:探索云计算的无限可能性
这里写目录标题 前言云计算介绍服务模型: 应用领域:云计算主要体现在生活中的地方云计算未来发展的方向 前言 云计算是一种基于互联网的计算模型,通过它可以实现资源的共享、存储、管理和处理。它已经成为许多个人、企业和组织的重要技术基础…...
【赋权算法】Python实现熵权法
在开始之前,我们先说一下信息熵的概念。 当一件事情发生,如果是意料之中,那么这个事情就并不能拿来当做茶余饭后的谈资,我们可以说这个事情并没有什么信息和价值。而当一件不可能发生的事情发生的时候,我们可能就会觉…...
docker之 Consul(注册与发现)
目录 一、什么是服务注册与发现? 二、什么是consul 三、consul 部署 3.1建立Consul服务 3.1.1查看集群状态 3.1.2通过 http api 获取集群信息 3.2registrator服务器 3.2.1安装 Gliderlabs/Registrator 3.2.2测试服务发现功能是否正常 3.2.3验证 http 和 ng…...
用NeRFMeshing精确提取NeRF网络中的3D网格
准确的 3D 场景和对象重建对于机器人、摄影测量和 AR/VR 等各种应用至关重要。 NeRF 在合成新颖视图方面取得了成功,但在准确表示底层几何方面存在不足。 推荐:用 NSDT编辑器 快速搭建可编程3D场景 我们已经看到了最新的进展,例如 NVIDIA 的…...
权限提升-Windows本地提权-AT+SC+PS命令-进程迁移-令牌窃取-getsystem+UAC
权限提升基础信息 1、具体有哪些权限需要我们了解掌握的? 后台权限,网站权限,数据库权限,接口权限,系统权限,域控权限等 2、以上常见权限获取方法简要归类说明? 后台权限:SQL注入,数…...
深入了解Kubernetes(k8s):安装、使用和Java部署指南(持续更新中)
目录 Docker 和 k8s 简介1、kubernetes 组件及其联系1.1 Node1.2 Pod1.3 Service 2、安装docker3、单节点 kubernetes 和 KubeSphere 安装3.1 安装KubeKey3.2 安装 kubernetes 和 KubeSphere3.3 验证安装结果 4、集群版 kubernetes 和 KubeSphere 安装5、kubectl 常用命令6、资…...
怎么样在网上推广/百度seo价格查询
require "PP";PP::pp [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #[3, 3, 5]...
政务服务网站建设技术因素/怎么做ppt
SELECT、POLL/EPOLL、IOCP,以及ACE、libevent、BOOST-ASIO等转载于:https://www.cnblogs.com/snailrun/p/5183495.html...
ui素材网站/陕西seo公司
在网络上搜索相关的很多资料,总结了一下,发生这种情况的原因主要是由于排序规则引起的:不指定排序规则的话 临时表是否区分大小写,与tempdb数据库的排序有关. 数据库对象是否区分大小写,与数据库本身的排序规则有关. 变量是否区分大小写,与数据库本身的排序规则…...
福鼎手机网站建设/网站自然排名工具
5.11.6.原生分区表最佳实践 分区表的选择要考虑详细,否则会影响查询性能。 设计原则中最重要的是考虑用哪列或哪几列作为分区键。其中一个较好的准则是,使用在where条件中出现最多的列进行分区。这样可以在查询时进行分区排除。不过,也可能需…...
做网站的宣传单素材/太原网站建设方案优化
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼程序:/*整体移动字符串,空位以\0补齐。左移为正,右移为负。右移时,可以扩展直接舍去为四舍五入*/// 规定E为字符串结束符int move( char *p, int n ){char *p_0 p;char *p_max p L…...
网上接网站开发类订单的平台/建站系统哪个比较好
了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1、被忽略的this 例如在使用bind 方法时候进行函数柯里化,如果此时函数并没有打算绑定任何对象在…...