go语言之不必要的拷贝

news/2024/6/3 7:19:03 标签: golang

其实我也是个golang开发者~~

Go语言本来就以轻量快速著称,一位GitHub员工却偶然发现:

只改变一个字符的位置,能把一段代码运行速度提高足足42%

简直就像是……

这个简单有效的技巧一经发布,就引来众多程序员围观。

原作者自己也调侃,一般这种情况都是事先犯了个愚蠢的错误,后面才能提升这么大。

不过顺着这个思路发现有人发现,就连Go开发团队的核心人物Russ Cox都在标准库中犯过同样的错误

什么样的错误?

发现这个问题的Harry在大型程序员交友平台GitHub工作。

他在开发一个把GitHub仓库中每个文件的所有者列出来的小工具。

功能很简单,就是根据CODEOWNERS文件中定义的规则匹配,写在越下面的规则优先级越高。

原理也很简单,就是从后往前一条一条处理,匹配到了就停止。

但就是这样一个简单的程序却出现了性能问题,处理中等大小的仓库就很慢了。

他打印出火焰图,发现大部分时间都花在了Go语言的正则表达式引擎中。

另外在内存动态分配malloc垃圾回收gc上面的花费也值得注意。

要减少malloc的时间,就需要用到Go语言的逃逸分析(Escape Analysis)了。

简单来说,就是尽量把变量分配到栈上,让编译器自动管理内存的释放。

只有在“逃逸”也就是变量的作用域超出所在的栈时,才把变量分配到堆上,减轻运行时GC的压力。

在这次的程序中,Harry确定了逃逸的变量是rule这个结构体(struct)。

但问题是,rule存储在RuleSet这个切片(slice)里,按Go语言的规则可以确信他已经在堆中了。

再分析一下代码,发现在给rule赋值的时候实际上是做了一次不必要的拷贝,后面用“&”取地址时候创建了一个逃逸的指针指向它的副本。

 最后解决办法也很容易想出,只需要把&移动到上面。

这样就引用了切片中的结构体,避免了拷贝。

如何彻底避免?

在热议中,有网友分享了自己是怎么避免出现这个问题的。

对于每个结构体,把它看作纯值或纯指针,压根就不去使用&这种取地址的操作,避免隐式的内存分配。


 如果你想要深入理解这个问题,也有人贴心的给出了需要提前了解的一些背景知识。 

最后有人指出,Rust语言为避免这个问题,直接规定必须显式操作才能拷贝一个数据结构。 

当你不习惯的时候这规定烦得要命,但是总的来看还是值得。

方便or规范,你更倾向于哪种做法?

说到这好想尝尝rust呀           whaosoft aiot  http://143ai.com

  


http://www.niftyadmin.cn/n/10230.html

相关文章

Vue3留言墙项目——主体部分静态、mock

文章目录主体头部主体关键部分小卡片组件创建mock数据以及使用主体头部 主体部分显示的内容,根据头部点击的是留言墙还是照片墙的按钮,显示不同的内容。 将照片墙和留言墙要渲染的数据抽取到一个js中,在导入的Main.vue(主体页面&…

Java之反射相关知识补充

Java之反射一、概述1、静态语言和动态语言1.1 静态语言1.2 动态语言2、Reflection(反射)2.1 介绍2.2 流程2.3 Java反射机制提供的功能2.4 优缺点(1)优点(2)缺点2.5 反射相关主要API2.6 示例二、反射相关操作1、获取Class类的实例1…

Git工具使用全解

Git工具使用全解 文章目录Git工具使用全解1.企业开发中的版本控制器2.Git工具的使用场景3.Git工具操作流程(三板斧操作)4.Git工具的安装与常用命令4.1 Git的安装4.2 Git基本操作指令5.Git工具常见问题解决5.1 常见问题:分支冲突解决办法5.2 常见问题:合并…

计算机毕业设计之java+ssm社会保险养老系统

项目介绍 自“金保工程”在全国实施以来,促进了劳动和社会保障工作处理方法全面完善,可以把社会保险注册、登记、申请、审核、收取、给付、核查、资金账户、社保管理以及劳动力市场相结合,实现劳动就业、择业、创业和社会保险管理品台的共享…

C++ Builder XE RzCheckTree1的树形显示用法

/*------------------------------------- 创建属性项 -------------------------------------*/ void __fastcall TMainForm::ItemsCreate() { //创建新组TTreeNode *RootA,*RootB,*RootC,*RootD; RootARzCheckTree1->Items->Add(NULL,"A-常用指标"…

【Java第32期】:Spring 中普通Maven项目的创建

作者:有只小猪飞走啦 博客地址:https://blog.csdn.net/m0_62262008?typeblog 内容:Spring 中普通Maven项目的创建 文章目录前言一,创建Spring项目1.创建一个普通的Maven项目2,添加Spring框架3,添加启动类…

Java接口的应用

目标:总结Comparable接口以及compareTo方法、comparator接口中compare方法比较器、toString方法、equals方法、hashCode方法、Cloneable接口以及深浅拷贝 比较对象中内容的大小【Comparable接口以及compareTo方法】 例如:学生类:成员有姓名、…

【ESP8266与ESP12E 电机拓展板握手】

【ESP8266与ESP12E 电机拓展板握手】 1. 前言2. 材料3. 工作原理3.1 板载功能3.2 引脚接口定义图3.3 产品技术规格4. 方案4.1 普通马达接线图4.2 42步进电机接线图5. 相关代码5.1 直流电机的管理代码5.2 步进电机管理代码6. 应用7. 来源1. 前言 ESP12E Motor Shield 是一块扩展…