性能优化的十个建议

2024-05-25 20:32
文章标签 优化 性能 建议 十个

本文主要是介绍性能优化的十个建议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、不进行升级。

很多人抱怨他们的系统不够快,并通过编写更好的算法和数据结构来寻求帮助,Thompson认为实际上“他们所需的仅仅就是进行升级”。升级操作系统、JVM、CLR等等。不进行升级的常见借口就是“在新版本中可能会有bug。”

为了避免这种状况,可以进行定期的持续集成和测试,这应该是开发流程的基础组成部分。Thompson以一个实时系统进行了例证,开发人员针对新版本的数据库进行了测试,在所有的测试通过之后,他们就将其发布到了生产环境之中。

2、重复性的工作。

Thompson讲述了某个系统的故事,这个系统是用来提供Web页面的,它非常缓慢,开发人员最初认为是数据库的问题并试图在这方面进行调优。但是当他在系统上运行profiler时,发现在一个循环中,ORM被调用了7,000次,这才是页面加载缓慢的罪魁祸首。当这个循环的问题修复之后,系统的响应变得完全正常。这里学到的经验就是“对系统进行度量。如果系统是一个黑盒的话,你就无法说明时间都耗费在了哪里。”

3、加载性能依赖于数据。

Thompson展现了一个基准测试结果,它会执行一项操作,该操作会对内存(RAM)中1GB数组的所有long型进行求和。这里所耗费的时间取决于内存是如何访问的,如下面的表格所示:

这个基准测试的结果显示并非所有的内存操作都是等价的,我们需要关注它是如何进行处理的。Thompson认为非常重要的一点在于了解各种数据结构的性能,他指出对于2GB以上的场景,Java的HashMap要比.NET的Dictionary慢十倍以上。他还补充说,也有一些场景.NET要比Java慢得多。

4、分配的内存太多。

尽管在很多场景中,内存分配几乎是没有什么成本的,但是它们的回收却并非如此,因为在面对大量的数据集时,垃圾收集器需要更多的时间。当分配大量的数据时,缓存会被填满,较旧的数据会被舍弃,使得在数据操作上的效率变为90ns/op而不是7ns/op,这里变慢了不止一个数量级。

5、 采用并行。

尽管对于特定的算法来说,采用并行很有吸引力,但是它也有一些局限性和相关的开销。Thompson引用了“可扩展性!但是其COST如何?”这篇论文,论文的作者通过引入COST(胜过单线程的配置,Configuration that Outperforms a Single Thread)对比了并行系统以及单线程的系统,COST的定义如下:

在特定的平台中,特定问题的COST指的是优于单线程方案所需的硬件配置。COST将系统的扩展性与系统所引入的开销进行了权衡,并指明了系统实际所能取得的性能,它们可能并没有带来实际的收益,却增加了并行所引入了开销。

作者分析了各种数据并行系统的测量结果,并得出如下的结论:“很多的系统要么具有非常高的COST,通常会需要上百个核心,要么针对他们所报告的配置,其性能要比单线程方案更差。”

在这个话题中,Thompson指出,并行任务会有相关的通信和同步开销,并且有些活动本质上要求是串行的,不能实现并行。按照Amdahl定律,如果系统中有5%的活动需要串行,那么不管使用了多少个处理器,系统的速度提升最多只能达到20倍。

Thompson还提到了Neil J. Gunther在1993年所提出的通用可扩展性定律(Universal Scalability Law,PDF),该定律指出在并行非共享系统(shared-nothing)中甚至会存在更多的局限性,当所使用的处理器数量达到一定程度后,速度会出现下降,这取决于并发、竞争以及同步的水平。(更多的细节可以参考如何量化可扩展性这个页面。)按照上述两个规律所总结的速度与处理器数量之间的关系如下图所示:

Thompson指出通过USL能够看到性能的下降,这要归因于并行系统中组件之间进行通信所消耗的成本:“在系统中,所投入资源越多,通信路径也会随之增多,这会使算法的效率降低。”

Thompson补充说,在构建并行系统时,主要的建议是避免共享可变(mutable)的状态,因为“它非常难以进行判断……最终你会遇到很多的bug”。推荐的方式是要么采用非共享架构,要么针对特定的一块数据,只使用一个写入器。

对这个性能问题,他的最终建议:如果你想提升算法的速度的话,在尝试并行方案之前,先设法提升单线程版本的性能,因为并行方案实在是太难了。

6、不理解TCP。

针对这个话题,Thompson认为很多在考虑微服务架构的人对TCP并没有充分的理解。在特定的场景中,有可能会遇到延迟的ACK,它会限制链路上所发送的数据包,每秒钟只会有2-5个数据包。这是因为TCP两个算法所引起的死锁:Nagle以及TCP Delayed Acknowledgement。在200-500ms的超时之后,会打破这个死锁,但是微服务之间的通信却会分别受到影响。推荐的方案是使用TCP_NODELAY,它会禁用Nagle的算法,多个更小的包可以依次发送。按照Thompson的说法,其中的差别在5到500 req/sec。

7、同步通信。

客户端和服务器之间的同步通信会带来时间的损耗,对于需要快速通信的系统来说,这会成为一个问题。Thompson说,它的解决方案并不是购买更加昂贵和快速的硬件,而是使用异步通信。在这种场景下,客户端可以发送多个请求到服务器端,而不必等待它们之间的响应。采用这种方式需要改变客户端发送请求的方式,但这是值得的。

8、文本编码。

开发人员很多时候会选择使用文本编码格式实现链路上的数据传输,比如JSON、XML或Base64,因为“这对人类是可读的”。但是Thompson指出在两个系统之间进行对话的时候,是没有人读这些数据的。借助这种方式,使用简单的文本编辑器就能很容易地进行调试,但是在将二进制数据与文本之间进行互相转换的时候,这会带来很高的CPU损耗。该问题的解决方案是使用能够理解二进制的更好的工具,Thompson提到了Wireshark。

9、API设计。

按照Thompson的说法,有一些与性能相关的最负面影响是由API引起的。它使用如下的代码来阐述较差的代码签名:

public void startElement( String uri, String localName, String qName, Attributes atts) throws SAXException

描述:

在处理XML的时候,通常我们并不会使用这些值[三个String以及属性的集合]。我们分配了很多的内容,但是却将其浪费并抛弃掉了。这会损耗电池的寿命,白白地浪费资源。我们需要使其更加简单一些。

他建议采用如下的签名,实现更加简单的方法:

public void characters( char[] ch, int start, int length) throws SAXException

有些人可能会抱怨后面的这个方法要比前一个更难用,Thompson建议采用组合的方式,将其中一个用另一个封装起来,这样的话,能够给用户多一个选择。如果性能不是什么问题的话,可以采用第一种(使用String),否则的话,第二个方案会更好一些。

Thompson提到的第二个样例是字符串拆分:

public String[] split(String regex)

这个方法签名相关的性能问题包括:

  • 每次方法调用的时候,正则表达式都需要进行编译;

  • 需要实例化一个动态的结构,用来存储字符串中所包含的初始数量未知的token;

  • 返回的结构是一个固定大小的数组,这就必须要将token收集到一个临时的结构中,然后再拷贝到数组里面;

  • 如果调用者想要对这些token进行一些操作的话,比如排序,需要将它们拷贝到另外一个结构之中。

更好的方案是使用Iterable,它能够避免在内存中创建中间状态的token副本:

public Iterable split(String regex)

另外一种方案是允许调用者提供存储token的集合。如果调用者想要对token列表去重的话,应该传递一个Set进来,如果想得到有序列表的话,就需要传递一个TreeMap进来:

public void split( String regex, Collection dst)

10、日志。

Thompson所列的排名第一的性能问题是写日志所耗费的时间。他通过一个图表展现了当线程数增加的时候,日志操作所耗费的平均时间:

这个图显示了一个100%的顺序操作,不管使用多少线程来记录日志,所需的时间均呈线性增长。Thompson说大多数已有的日志系统都可以得出这样一幅图表,“Logger是系统中最大的瓶颈之一”。这个问题的解决方案是使用异步的Logger。

另外,Logger所记录的数据应该是结构化的数据,便于后续的工具进行读取和处理,而不应该是一堆String。如果是记录重复的错误,他建议在错误第一次出现的时候进行记录,后续出现时只需对一个计数器进行递增,告知对应的错误出现了多少次即可。对于实时系统的调试,Thompson建议使用代码编织(code weaver)的技术,如Byte Buddy,因为它能够避免编写和运行不必要的日志代码。

这篇关于性能优化的十个建议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1002552

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

PR曲线——一个更敏感的性能评估工具

在不均衡数据集的情况下,精确率-召回率(Precision-Recall, PR)曲线是一种非常有用的工具,因为它提供了比传统的ROC曲线更准确的性能评估。以下是PR曲线在不均衡数据情况下的一些作用: 关注少数类:在不均衡数据集中,少数类的样本数量远少于多数类。PR曲线通过关注少数类(通常是正类)的性能来弥补这一点,因为它直接评估模型在识别正类方面的能力。 精确率与召回率的平衡:精确率(Pr