当前位置:首页 > 数码 > 六种优化您的-运行性能的方法-Go (优化方法有哪几种)

六种优化您的-运行性能的方法-Go (优化方法有哪几种)

admin4个月前 (05-07)数码16

优化您的Go运行程序

1.假设您的运行程序在Kubees中运转,请智能设置GOMAXPROCS以婚配容器的CPU配额

Go调度器可以具备与运转设备的外围数量一样多的线程。由于咱们的运行程序在Kubernetes环境中的节点上运转,当咱们的Go运行程序开局运转时,它可以领有与节点中的外围数量一样多的线程。由于许多不同的运行程序在这些节点上运转,因此这些节点或许蕴含相当多的外围。

经过经常使用,Go调度器经常使用的线程数量将与您在k8syaml中定义的CPU限度一样多。

我观察到在我实施这个方法的运行程序中有相当大的性能优化。约60%的CPU经常使用率,约30%的内存经常使用率和约30%的照应期间。

2.对结构体字段启动排序

结构体中字段的顺序间接影响您的内存经常使用状况。

例如:

typetestStructstruct{testBool1bool//1bytetestFloat1float64//8bytestestBool2bool//1bytetestFloat2float64//8bytes}

您或许会以为这个结构体将占用18字节,但实践上不会。

funcmn(){a:=testStruct{}fmt.Println(unsafe.Sizeof(a))//32bytes}

这是由于在64位架构中外部内存对齐的上班形式。

manyboxesshowing8bytesoftestbool1,testFIoat1,testbool2,testFIoat2

咱们如何降落内存经常使用?咱们可以依据内存填充来对字段启动排序。

typetestStructstruct{testFloat1float64//8bytestestFloat2float64//8bytestestBool1bool//1bytetestBool2bool//1byte}funcmain(){a:=testStruct{}fmt.Println(unsafe.Sizeof(a))//24bytes}

咱们并不总是须要手动排序这些字段。您可以经常使用诸如fieldalignment等工具来智能对结构体启动排序。

fieldalignment-fix./...

3.渣滓回收调优

在Go1.19之前,咱们只能经常使用GOGC(runtime/debug.SetGCPercent)来性能渣滓回收周期;但是,在某些状况下,咱们或许会超出内存限度。随着Go1.19的来到,咱们如今领有了GOMEMLIMIT。GOMEMLIMIT是一个新的环境变量,准许用户限度Go进程可以经常使用的内存量。这特性能提供了更好的控制Go运行程序内存经常使用的形式,防止它们经常使用过多的内存造成性能疑问或解体。经过设置GOMEMLIMIT变量,用户可以确保其Go程序在系统上颠簸高效地运转,而不会对系统形成不用要的压力。

它并不代替GOGC,而是与之配合经常使用。您还可以禁用GOGC百分比性能,只经常使用GOMEMLIMIT来触发渣滓回收。

GOGC设为100和内存限度为100MB

GOGC设为封锁(off)并且内存限度为100

在缩小渣滓回收的运转量方面有清楚的成果,但在运行此设置时须要小心。假设您不了解运行程序的极限,请不要将GOGC=off。

4.经常使用unsafe包启动字符串<->字节转换而不启动复制

在字符串与字节之间启动转换时,咱们通常会启动变量的复制。但在Go外部,这两种类型通经常常使用StringHeader和SliceHeader值。咱们可以在这两种类型之间启动转换,而不启动额外的调配。

//ForGo1.20andhigherfuncStringToBytes(sstring)[]byte{returnunsafe.Slice(unsafe.StringData(s),len(s))}funcBytesToString(b[]byte)string{returnunsafe.String(unsafe.SliceData(b),len(b))}//Forlowerversions//Checktheexamplehere//

诸如fasthttp和fiber等库也在其外部经常使用这种结构。

留意:假设您的字节或字符串值或许会在后续出现更改,请不要经常使用此特性。

5.经常使用jsoniter代替encoding/json

咱们通常在代码中经常使用Marshal和Unmarshal方法来启动序列化或反序列化。

Jsoniter是encoding/json的100%兼容的代替品。

以下是一些性能基准:

将其交流为encoding/json十分便捷:

import"encoding/json"json.Marshal(&data)json.Unmarshal(input,&data)importjsoniter"github.com/json-iterator/go"varjson=jsoniter.ConfigCompatibleWithStandardLibraryjson.Marshal(&data)json.Unmarshal(input,&data)

6.经常使用sync.Pool来缩小堆调配

对象池面前的关键概念是防止重复创立和销毁对象的开支,这或许会对性能发生负面影响。

缓存先前调配但未经常使用的名目有助于减轻渣滓回收器的累赘,并准许稍后从新经常使用它们。

以下是一个示例:

typePersonstruct{Namestring}varpool=sync.Pool{New:func()any{fmt.Println("Creatinganewinstance")return&Person{}},}funcmain(){person:=pool.Get().(*Person)fmt.Println("Getobjectfromsync.Poolforthefirsttime:",person)person.Name="Mehmet"fmt.Println("Puttheobjectbackinthepool")pool.Put(person)fmt.Println("Getobjectfrompoolagain:",pool.Get().(*Person))fmt.Println("Getobjectfrompoolagain(newonewillbecreated):",pool.Get().(*Person))}//Creatinganewinstance//Getobjectfromsync.Poolforthefirsttime:&{}//Puttheobjectbackinthepool//Getobjectfrompoolagain:&{Mehmet}//Creatinganewinstance//Getobjectfrompoolagain(newonewillbecreated):&{}

经过经常使用sync.Pool,我处置了NewRelicGoAgent中的内存走漏疑问。以前,它为每个恳求创立一个新的gzipwriter。我创立了一个池,以便代理程序可以经常使用该池中的writer,而不是为每个恳求创立新的gzipwriter实例,从而大大缩小了堆经常使用,并因此缩小了系统的渣滓回收次数。这个改良大概将咱们运行程序的CPU经常使用率降落了约40%,内存经常使用率降落了约22%。


GO语言商业案例(十八):stream

切换到新语言始终是一大步,尤其是当您的团队成员只有一个时有该语言的先前经验。现在,Stream 的主要编程语言从 Python 切换到了 Go。这篇文章将解释stream决定放弃 Python 并转向 Go 的一些原因。

Go 非常快。性能类似于 Java 或 C++。对于用例,Go 通常比 Python 快 40 倍。

对于许多应用程序来说,编程语言只是应用程序和数据库之间的粘合剂。语言本身的性能通常并不重要。然而,Stream 是一个API 提供商,为 700 家公司和超过 5 亿最终用户提供提要和聊天平台。多年来,我们一直在优化 Cassandra、PostgreSQL、Redis 等,但最终,您会达到所使用语言的极限。Python 是一门很棒的语言,但对于序列化/反序列化、排名和聚合等用例,它的性能相当缓慢。我们经常遇到性能问题,Cassandra 需要 1 毫秒来检索数据,而 Python 会花费接下来的 10 毫秒将其转换为对象。

看看我如何开始 Go 教程中的一小段 Go 代码。(这是一个很棒的教程,也是学习 Go 的一个很好的起点。)

如果您是 Go 新手,那么在阅读那个小代码片段时不会有太多让您感到惊讶的事情。它展示了多个赋值、数据结构、指针、格式和一个内置的 HTTP 库。当我第一次开始编程时,我一直喜欢使用 Python 更高级的功能。Python 允许您在编写代码时获得相当的创意。例如,您可以:

这些功能玩起来很有趣,但是,正如大多数程序员会同意的那样,在阅读别人的作品时,它们通常会使代码更难理解。Go 迫使你坚持基础。这使得阅读任何人的代码并立即了解发生了什么变得非常容易。 注意:当然,它实际上有多“容易”取决于您的用例。如果你想创建一个基本的 CRUD API,我仍然推荐 Django + DRF或 Rails。

作为一门语言,Go 试图让事情变得简单。它没有引入许多新概念。重点是创建一种非常快速且易于使用的简单语言。它唯一具有创新性的领域是 goroutine 和通道。(100% 正确CSP的概念始于 1977 年,所以这项创新更多是对旧思想的一种新方法。)Goroutines 是 Go 的轻量级线程方法,通道是 goroutines 之间通信的首选方式。Goroutines 的创建非常便宜,并且只需要几 KB 的额外内存。因为 Goroutine 非常轻量,所以有可能同时运行数百甚至数千个。您可以使用通道在 goroutine 之间进行通信。Go 运行时处理所有复杂性。goroutines 和基于通道的并发方法使得使用所有可用的 CPU 内核和处理并发 IO 变得非常容易——所有这些都不会使开发复杂化。与 Python/Java 相比,在 goroutine 上运行函数需要最少的样板代码。您只需在函数调用前加上关键字“go”:

Go 的并发方法很容易使用。与 Node 相比,这是一种有趣的方法,开发人员必须密切关注异步代码的处理方式。Go 中并发的另一个重要方面是竞争检测器。这样可以很容易地确定异步代码中是否存在任何竞争条件。

我们目前用 Go 编写的最大的微服务编译需要 4 秒。与以编译速度慢而闻名的 Java 和 C++ 等语言相比,Go 的快速编译时间是一项重大的生产力胜利。我喜欢在程序编译的时候摸鱼,但在我还记得代码应该做什么的同时完成事情会更好。

首先,让我们从显而易见的开始:与 C++ 和 Java 等旧语言相比,Go 开发人员的数量并不多。根据StackOverflow的数据, 38% 的开发人员知道 Java, 19.3% 的人知道 C++,只有 4.6% 的人知道 Go。GitHub 数据显示了类似的趋势:Go 比 Erlang、Scala 和 Elixir 等语言使用更广泛,但不如 Java 和 C++ 流行。幸运的是,Go 是一种非常简单易学的语言。它提供了您需要的基本功能,仅此而已。它引入的新概念是“延迟”声明和内置的并发管理与“goroutines”和通道。(对于纯粹主义者来说:Go 并不是第一种实现这些概念的语言,只是第一种使它们流行起来的语言。)任何加入团队的 Python、Elixir、C++、Scala 或 Java 开发人员都可以在一个月内在 Go 上发挥作用,因为它的简单性。与许多其他语言相比,我们发现组建 Go 开发人员团队更容易。如果您在博尔德和阿姆斯特丹等竞争激烈的生态系统中招聘人员,这是一项重要的优势。

对于我们这样规模的团队(约 20 人)来说,生态系统很重要。如果您必须重新发明每一个小功能,您根本无法为您的客户创造价值。Go 对我们使用的工具有很好的支持。实体库已经可用于 Redis、RabbitMQ、PostgreSQL、模板解析、任务调度、表达式解析和 RocksDB。与 Rust 或 Elixir 等其他较新的语言相比,Go 的生态系统是一个重大胜利。它当然不如 Java、Python 或 Node 之类的语言好,但它很可靠,而且对于许多基本需求,你会发现已经有高质量的包可用。

Gofmt 是一个很棒的命令行实用程序,内置在 Go 编译器中,用于格式化代码。就功能而言,它与 Python 的 autopep8 非常相似。我们大多数人并不真正喜欢争论制表符与空格。格式的一致性很重要,但实际的格式标准并不那么重要。Gofmt 通过使用一种正式的方式来格式化您的代码来避免所有这些讨论。

Go 对协议缓冲区和 gRPC 具有一流的支持。这两个工具非常适合构建需要通过 RPC 通信的微服务。您只需要编写一个清单,在其中定义可以进行的 RPC 调用以及它们采用的参数。然后从这个清单中自动生成服务器和客户端代码。生成的代码既快速又具有非常小的网络占用空间并且易于使用。从同一个清单中,您甚至可以为许多不同的语言生成客户端代码,例如 C++、Java、Python 和 Ruby。因此,内部流量不再有模棱两可的 REST 端点,您每次都必须编写几乎相同的客户端和服务器代码。.

Go 没有像 Rails 用于 Ruby、Django 用于 Python 或 Laravel 用于 PHP 那样的单一主导框架。这是 Go 社区内激烈争论的话题,因为许多人主张你不应该一开始就使用框架。我完全同意这对于某些用例是正确的。但是,如果有人想构建一个简单的 CRUD API,他们将更容易使用 Django/DJRF、Rails Laravel 或Phoenix。对于 Stream 的用例,我们更喜欢不使用框架。然而,对于许多希望提供简单 CRUD API 的新项目来说,缺乏主导框架将是一个严重的劣势。

Go 通过简单地从函数返回错误并期望调用代码来处理错误(或将其返回到调用堆栈)来处理错误。虽然这种方法有效,但很容易失去问题的范围,以确保您可以向用户提供有意义的错误。错误包通过允许您向错误添加上下文和堆栈跟踪来解决此问题。另一个问题是很容易忘记处理错误。像 errcheck 和 megacheck 这样的静态分析工具可以方便地避免犯这些错误。虽然这些变通办法效果很好,但感觉不太对劲。您希望该语言支持正确的错误处理。

Go 的包管理绝不是完美的。默认情况下,它无法指定特定版本的依赖项,也无法创建可重现的构建。Python、Node 和 Ruby 都有更好的包管理系统。但是,使用正确的工具,Go 的包管理工作得很好。您可以使用Dep来管理您的依赖项,以允许指定和固定版本。除此之外,我们还贡献了一个名为的开源工具VirtualGo,它可以更轻松地处理用 Go 编写的多个项目。

我们进行的一个有趣的实验是在 Python 中使用我们的排名提要功能并在 Go 中重写它。看看这个排名方法的例子:

Python 和 Go 代码都需要执行以下操作来支持这种排名方法:

开发 Python 版本的排名代码大约花了 3 天时间。这包括编写代码、单元测试和文档。接下来,我们花了大约 2 周的时间优化代码。其中一项优化是将分数表达式 (simple_gauss(time)*popularity) 转换为抽象语法树. 我们还实现了缓存逻辑,可以在未来的特定时间预先计算分数。相比之下,开发此代码的 Go 版本大约需要 4 天时间。性能不需要任何进一步的优化。因此,虽然 Python 的最初开发速度更快,但基于 Go 的版本最终需要我们团队的工作量大大减少。另外一个好处是,Go 代码的执行速度比我们高度优化的 Python 代码快大约 40 倍。现在,这只是我们通过切换到 Go 体验到的性能提升的一个示例。

运行性能的方法

与 Python 相比,我们系统的其他一些组件在 Go 中构建所需的时间要多得多。作为一个总体趋势,我们看到 开发 Go 代码需要更多的努力。但是,我们花更少的时间 优化 代码以提高性能。

我们评估的另一种语言是Elixir.。Elixir 建立在 Erlang 虚拟机之上。这是一种迷人的语言,我们之所以考虑它,是因为我们的一名团队成员在 Erlang 方面拥有丰富的经验。对于我们的用例,我们注意到 Go 的原始性能要好得多。Go 和 Elixir 都可以很好地服务数千个并发请求。但是,如果您查看单个请求的性能,Go 对于我们的用例来说要快得多。我们选择 Go 而不是 Elixir 的另一个原因是生态系统。对于我们需要的组件,Go 有更成熟的库,而在许多情况下,Elixir 库还没有准备好用于生产环境。培训/寻找开发人员使用 Elixir 也更加困难。这些原因使天平向 Go 倾斜。Elixir 的 Phoenix 框架看起来很棒,绝对值得一看。

Go 是一种非常高性能的语言,对并发有很好的支持。它几乎与 C++ 和 Java 等语言一样快。虽然与 Python 或 Ruby 相比,使用 Go 构建东西确实需要更多时间,但您将节省大量用于优化代码的时间。我们在Stream有一个小型开发团队,为超过 5 亿最终用户提供动力和聊天。Go 结合了 强大的生态系统 、新开发人员的 轻松入门、快速的性能 、对并发的 可靠支持和高效的编程环境 ,使其成为一个不错的选择。Stream 仍然在我们的仪表板、站点和机器学习中利用 Python 来提供个性化的订阅源. 我们不会很快与 Python 说再见,但今后所有性能密集型代码都将使用 Go 编写。我们新的聊天 API也完全用 Go 编写。

手机打游戏卡顿的解决方法

若使用的是vivo手机,玩游戏时出现的卡顿现象,建议参考以下方法:

1、排查网络情况

请确保连接稳定的Wi-Fi或数据网络,如果网络状况不好,游戏过程中容易出现操作延迟、卡顿、掉线等情况;

2、检查省电模式和电量情况

省电模式会降低设备部分性能以延长设备续航时间,如果开启低电模式,可能导致程序卡顿,建议您进入【设置 > 电池】,关闭省电模式(低电模式),如果电量过低,请及时给设备充电后使用;

3、调整游戏模式和游戏设置

可尝试调出游戏侧边栏,开启性能模式(BOOST/Monster模式),或适当降低游戏参数设置,以改善游戏体验。

*注:游戏画质、抗锯齿等显示效果越高,系统负载越重,更容易导致发热、游戏运行不稳定等情况,建议在不影响视觉体验的情况下适当调整降低游戏画质等显示效果。

4、检查设备发热情况

手机温度较高时会适当降低系统性能,以减少运行功耗和发热,可能导致游戏暂时出现卡顿现象,建议进入【i管家>实用工具>手机降温】,对设备进行降温,同时尽量避免边充电边玩游戏以免设备温度过高;

5、检查屏幕刷新率

进入【设置>显示与亮度>屏幕刷新率】,调节到高刷新率,高刷新率比60Hz标准刷新率能带来更加流畅的动态画面显示。(如果看不到“屏幕刷新率”设置选项,则代表该机型采用60Hz标准刷新率,不支持设置高刷新率)

6、清理内存

由于设备运行内存可用空间过小、存储内存可用空间过小(建议保留20%以上空间)都会导致卡顿反应慢。

可以选择以下方法操作:

(1)底部上滑并停顿进入后台,清理暂时不用的后台程序;

(2)进入i管家,点击“一键优化”对手机进行优化,必要时可通过“空间清理”释放更多空间。

7、设备配置

确认游戏配置要求,如果手机不满足大型游戏的配置要求,可能会出现卡顿、闪退、无法运行等情况。

如果尝试了以上方法后仍然无法解决设备出现的情况,请携带设备、购机凭证前往vivo客户服务中心处理。(客户服务中心地址:进入vivo官网/vivo商城APP--我的--服务网点/售后网点--选择省市进行查询客户服务中心地址)

建议提前致电客户服务中心,确认相关事宜和了解上班时间在前往,以免耽误宝贵时间。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Go

“六种优化您的-运行性能的方法-Go (优化方法有哪几种)” 的相关文章

中-Goroutines-成功轻量级并发的高效并发原语-Go

中-Goroutines-成功轻量级并发的高效并发原语-Go

并发是现代软件开发的一个基本概念,使程序能够同时口头多个义务。在Go编程畛域,了解Goroutines是至关关键的。本文将片面概述Goroutines,它们的轻量级特性,如何经常使用go关键字创立...

Go-言语中并发的弱小效劳 (go语言语法很奇怪啊)

Go-言语中并发的弱小效劳 (go语言语法很奇怪啊)

施展效率和照应才干 并发是现代软件开发中的一个基本概念,它使程序能够同时口头多个义务,提高效率和照应才干。在本文中,咱们将讨论并发在现代软件开发中的关键性,并深化了解Go处置并发义务的共同...

etcd-的依赖问题最终得到解决-Go (etcd的英文全称)

etcd-的依赖问题最终得到解决-Go (etcd的英文全称)

几年前,我经常接触到一组微服务相关组件:gRPC、gRPC 网关、etcd、Protobuf 和 protoc-gen-go。一开始,它们都能很好地协同工作,并且随着新版本的发布而持续更新。...

Go-内存调配优化-在结构体中充沛应用内存 (go 内存)

Go-内存调配优化-在结构体中充沛应用内存 (go 内存)

在经常使用Golang启动内存调配时,咱们须要遵照一系列规定。在深化了解这些规定之前,咱们须要先了解变量的对齐形式。 Golang的unsafe包中有一个函数Alignof,签名如下: f...

内存优化与渣滓搜集-深化探求优化程序性能的最佳通常-Go (内存优化与渣子有关吗)

内存优化与渣滓搜集-深化探求优化程序性能的最佳通常-Go (内存优化与渣子有关吗)

Go提供了智能化的内存治理机制,但在某些状况下须要更精细的微调从而防止出现OOM失误。本文将讨论Go的渣滓搜集器、运行程序内存优化以及如何防止OOM(Out-Of-Memory)失误。 Go...

的原因-Go-Map-语言不支持并发读写 (的原因英语)

的原因-Go-Map-语言不支持并发读写 (的原因英语)

在Go语言的设计中,为了防止数据竞态,不同于一些其他语言,map并没有提供内置的锁机制。这样设计的目的是为了鼓励开发者使用更加精细的同步措施,以适应不同的并发场景。 Map的数据结构...

内存效率-多用途-语言中使用切片代替数组的优点-动态大小-Go (内存使用效率)

内存效率-多用途-语言中使用切片代替数组的优点-动态大小-Go (内存使用效率)

引言 在 Go 语言中,数组是一种固定长度的数据结构,而切片则是一种可变长度的数据结构。虽然数组和切片都可以存储相同类型的数据元素,但切片在使用上有其独到的优势,本文将通过介绍切片的特性来解释为...

14条超乎想象的Go接口最佳实践

14条超乎想象的Go接口最佳实践

近年来,越来越多的开发者开始关注 Go 语言,它以其高效、简洁和高并发性而闻名。在 Go 语言中,接口是一个非常强大的特性,它可以帮助我们定义和实现不同的行为。本文将介绍 Go 语言中接口设计的一...