Go语言高效编程的3个技巧总结
作者:InterestingFigure 发布时间:2024-02-03 02:52:38
不要使用Logrus
这其实和泛型有关。因为Go语言是一门强类型的静态语言,所以你不可能像NodeJS或者PHP那样绕过数据类型。那如果我们还需要使用通用的类型怎么办呢?比如像Loger,或者ORM,因为只有使用了通用的类型,才能编写出通用的代码,不然每个都要写一次。
最终,我们只能用反射。而 Logrus 大量使用反射,这导致大量分配计数。虽然通常不是一个大问题(取决于代码),但性能很重要,尤其是在大规模、高并发的项目中。虽然这听起来像是一个非常小的优化,但避免反射很重要。如果你看到一些可以不考虑类型而使用结构的代码,它会使用反射并且会对性能产生影响。
例如,Logrus 并不关心类型,但显然 Go 需要知道(最终)。Logrus 怎么办呢?使用反射来检测类型,这是开销。
log.WithFields(log.Fields{<!--{C}%3C!%2D%2D%20%2D%2D%3E-->
“animal”: myWhatever,
}).Info(“A walrus appears”)
所以我会更喜欢zerolog,当然zap也不错。两者都宣称零分配,这也是我们希望的,因为它们的性能影响最小。
不要使用encoding/json
当我们需要一个功能、函数的时候,很多人都建议使用标准库。但是标准库中的encoding/json模块是个例外。其实也和上面的例子一样,encoding/json使用反射,这会导致性能不高,并且在编写返回 json 响应的 API 、或者微服务时会造成损失。
比如你可以使用 Easyjson,它很简单,也很高效,它是使用代码生成器来创建将结构转换为 json 所需的代码,以最大限度地减少分配。这是一个手动构建步骤,很烦人。有趣的是json-iterator也使用反射,但速度明显更快,我怀疑是黑魔法。
尽可能不要在goroutine中使用闭包
比如,下面这个示例代码:
for i:=0;i<10;i++ {
go func() {
fmt.Println(i)
}()
}
大多数人可能期望这会打印数字 0 到 9,就像将任务委托给 goroutine 时那样。
但是实际结果:根据系统,你将得到一两个数字和许多 10。
为什么会这样?闭包可以访问父作用域,因此可以直接使用变量。尽管更新的 linters 可能会警告你“变量闭包捕获”,但并不会要求你重新声明该变量。
Go 的性能名声很大程度上归功于执行的运行时优化,它尝试“猜测”你想要做什么并优化某些执行路径。在此期间,它“捕获”变量并以理论上最有效的方式将它们传递到需要它们的地方(例如,在完成一些非并发操作以释放某些 CPU 上的分配之后)。这种情况下的结果是循环可能会启动 goroutines,goroutines可能会在很晚之后从父作用域接收到 i 的值。不能保证在多次执行此代码时你会看到哪个,可能是数字10,也可以是其他数字。
如果你出于某种原因确实使用了闭包,一定要传递变量i,就像对待每个函数一样对待闭包。
来源:https://blog.csdn.net/Edu_enth/article/details/128490611


猜你喜欢
- 本文详细介绍了Python中类型关系和继承关系。分享给大家供大家参考。具体分析如下:如果一个对象A持有另一个对象B的ID,那么检索到A之后就
- 说下整体思路1、服务器安装ffmpeg2、使用ffmpeg -i 指令来转换amr为mp3格式(这个到时候写在PHP代码中,使用exec函数
- MySQL 出现错误1418 的原因分析及解决方法具体错误: 使用mysql创建、调用存储过程,函数以及触发器的时候会有错误符号为
- 本文实例讲述了JS闭包。分享给大家供大家参考,具体如下:之前花了很多时间看书上对闭包的介绍,也看了很多人的写的关于闭包的博客,然后我就以为自
- 我听说 Hooks 最近很火。讽刺的是,我想用一些关于 class 组件的有趣故事来开始这篇文章。你觉得如何?本文中这些坑对于你正常使用 R
- 本文用163邮箱进行了测试,python用的是3.8版本进行的测试1.设置邮箱,如下图所示2.设置过程如下图所示:设置完成后,添加如下代码:
- Javascript有许多内建的方法来产生对话框,如:window.alert(), window.confirm(),window.pro
-   跨平台的pywifi模块支持操作无线网卡,该模块易于使用,同时支持Windows、Linux等多个系
- 方法一:直接右键,将文章路径复制下来点击Copy full Xpath使用selenium+lxml中的etree进行配合使用,使用etre
- show.php源代码: <? if ($action=="cp"){ echo"<div ali
- 使用pip安装python库的几种方式1、使用pip在线安装1.1 安装单个package格式如下:pip install SomePack
- 前言CSRF全称Cross-site request forgery(跨站请求伪造),是一种网络的攻击方式,也被称为“One Click A
- 一、将对象转为json字符串json.dumps:将 Python 对象编码成 JSON 字符串json.loads:将已编码的 JSON
- Serilog是.net下的新兴的日志框架,本文这里简单的介绍一下它的用法。首先安装Nuget包:Install-Package Seril
- 本文实例讲述了Python异常模块traceback用法。分享给大家供大家参考,具体如下:traceback模块被用来跟踪异常返回信息. 如
- 数组编程使用Numpy数组可以使你利用简单的数组表达式完成多项数据操作任务,而不需要编写大量的循环,这个极大的帮助了我们高效的解决问题。我们
- 小孩子刚刚开始学说话的时候,常常是一个字一个字地开始学,比如学说“饺子”,对他/她来讲,似乎有点难度,大人也聪明,于是就简化了,用“饺饺”来
- 一、当我们用Python matplot时作图时,一些数据需要以百分比显示,以更方便地对比模型的性能提升百分比。二、借助matplotlib
- 功能所在位置该功能运用了django.contrib.messages这个库,再django项目中srtting.py文件中的38行,APP
- 异常捕捉:try: XXXXX1 raise Exception(“xxxxx2”) except (Exception1,Excepti