【编程素质】代码及性能优化

2024-02-20 12:48

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

1,思路

一般如果性能有问题,一般打印日志,在每一处输出消耗时间,看时间消耗在哪里。
如果是sql性能问题,查看执行计划,看慢在哪里,优化sql。
积硅步,致千里。

2,常用工具

1)StopWatch

除了下面介绍的方法外还有其它方法。以下为笔者习惯用法


import org.springframework.util.StopWatch;StopWatch stopWatch = new StopWatch("getSearchResult");stopWatch.start("total");Thread.sleep(1000);System.out.println("sql执行");stopWatch.stop();stopWatch.start("list合并计算");Thread.sleep(1000);System.out.println("list合并计算");stopWatch.stop();log.info("getSearchResult检索性能:{}", stopWatch.prettyPrint());

执行结果:

sql执行
list合并计算
11:11:54.141 [main] INFO com.luo.Adapter - getSearchResult检索性能:StopWatch 'getSearchResult': running time (millis) = 2000
-----------------------------------------
ms     %     Task name
-----------------------------------------
01000  050%  total
01000  050%  list合并计算

3,java编程规范

1)对象及方法

  1. 尽量指定类、方法的final修饰符;
  2. String:用equalsIgnoreCase()替代equals()
  3. Long、Integer等:用equals代替==
  4. 用StringBuffer(多线程)、StringBuilder替代String;
  5. 尽可能使用局部变量
  6. 尽量采用懒加载的策略,即在需要的时候才创建
//不好的示范
String str = "aaa";
if(i == 1) {list.add(str);
}
//建议替换为如下:
if(i == 1) {String str = "aaa";list.add(str);
}
  1. 异常只用于错误处理,不做其它用处。
  2. 当复制大量数据时,使用System.arraycopy()命令;
  3. 常量声明为static final,并以大写命名;
  4. 程序运行过程中避免使用反射
    不建议在程序运行过程中使用,除非万不得已,尤其是频繁使用反射机制,特别是Method的invoke方法,如果确实有必要,一种建议性的做法是将那些需要通过反射加载的类在项目启动的时候通过反射实例化出一个对象并放入内存,用户只关心和对端交互的时候获取最快的响应速度,并不关心对端的项目启动花多久时间。
  5. 不要让public方法中有太多的形参。
    public方法即对外提供的方法,如果给这些方法太多形参的话主要坏处是违反了面向对象的编程思想,Java讲求一切都是对象,太多的形参和面向对象的编程思想并不契合,参数太多势必导致方法调用的出错概率增加。
  6. 把一个基本数据类型转为字符串,基本数据类型.toString()是最快的方式、String.valueOf(数据)次之、数据+""最慢。
  7. 不用魔法数
  8. 用Objects.equals()替代a.equals(b);
  9. 用Integer.valueOf()替代new Integer();
  10. 数字添加下划线以方便阅读;(java7)

2)集合

  1. 必须明确存储最大规格;
  2. 取值前先判空(null和size=0);
  3. 数据获取:List<String> newList = Optional.ofNullable(list).orElse(Lists.newArrayList());
  4. 能用Array就不用ArrayList;
  5. 顺序插入和随机访问比较多的场景使用ArrayList,元素删除和中间插入比较多的场景使用LinkedList;
  6. 使用HashMap、ArrayList,多线程考虑Hashtable、Vector。
  7. 实现RandomAccess接口的集合(比如ArrayList)应当使用最普通的for循环而不是foreach循环来遍历。
    这是JDK推荐给用户的,JDK API对于RandomAccess接口的解释是实现RandomAccess接口用来表明其支持快速随机访问,此接口的主要目的是允许一般的算法更改其行为,从而将其应用到随机或连续访问列表时能提供良好的性能。实际经验表明,实现RandomAccess接口的类实例,假如是随机访问的,使用普通for循环效率将高于使用foreach循环,反过来,如果是顺序访问的,则使用Iterator会效率更高。
//样板代码:可以使用类似如下的代码作判断
if(list instanceof RandomAccess) {for(int i = 0; i < list.size(); i++) {}
} else {Iterator<?> iterator = list.iterable();while(iterator.hasNext()) {iterator.next()}
}
  1. 公用的集合类中不使用的数据一定要及时remove掉

3)循环

  1. 禁止在循环中修改循环控制变量;
  2. 禁止在循环中调用接口、访问数据库;
  3. 循环内不创建引用;
//不好的示范
for(int i = 1; i <= count; i++) {Object obj = new Object();
}
//上面这种做法会导致内存中有count份Object对象引用存在,
//count很大的话,就耗费内存了,建议为如下实现。
Object obj = null;
for(int i = 0; i <= count; i++) {obj = new Object();
}
//如上实现内存中只有一份Object对象引用,
//每次new Object()的时候,Object对象引用指向不同的Object罢了,
//但是内存中只有一份,这样就大大节省了内存空间了。

4)控制语句

  1. IF语句必须写ELSE;
  2. SWITCH语句必须写DEFAULT;
  3. for的循环判断 语句写常量;
//性能不好,list.size()会重复调用
for(int i = 0; i < list.size(); i++) {...
}
//建议替换为如下:
for(int i = 0, length = list.size(); i < length; i++) {...
}
//如上写法在list.size()很大的时候,就减少了很多的消耗。

5)获取资源

  1. 禁止一次性读入文件;
  2. finally里关闭资源;
  3. 尽量避免使用JSONObject与Map;
  4. 及时清除不再需要的会话。
    为了清除不再活动的会话,许多应用服务器都有默认的会话超时时间,一般为30分钟。当应用服务器需要保存更多的会话时,如果内存不足,那么操作系统会把部分数据转移到磁盘,应用服务器也可能根据MRU(最近最频繁使用)算法把部分不活跃的会话转储到磁盘,甚至可能抛出内存不足的异常。如果会话要被转储到磁盘,那么必须要先被序列化,在大规模集群中,对对象进行序列号的代价是很昂贵的。因此,当会话不再需要时,应当及时调用HttpSession的invalidate()方式清楚会话。
  5. 使用带缓冲的输入输出流进行IO操作
    带缓冲的输入输出流,即BufferedReader、BufferedWriter、BufferedInputStream、BufferedOutputStream,这可以极大地提升IO效率。
  6. 对资源的close()建议分开操作
    虽然有些麻烦,却能避免资源泄漏,这其实和try-catch机制相关,各自分开close各自的try-catch就会互不影响,防止写在一个try-catch中因为一个异常了后面的释放不了。

6)线程和同步

  1. 同步块粒度越小越好;
  2. 使用数据库连接池和线程池
    这两个池都是用于重用对象的,前者可以避免频繁的打开和关闭连接,后者可以避免频繁的创建和销毁线程。
  3. 对于ThreadLocal在线程池场景使用前或者使用后一定要先remove。

7)

4,sql规范

  1. SQL中出现数组、jsonb等集合类字段时,须说明最大存储规格,代码中明确存在限制逻辑;
  2. VARCHAR长度为2n-1,不能是2n;
  3. 可重复执行的;
  4. 建表必须有主键、create_time、update_time;

5,rest-api规范

6,原理

1)方法内联

在JVM运行期间的编译优化JIT过程里,会考虑内联方法来提升执行效能。方法内联就是把被调用的函数代码"复制"到调用方函数中!以空间换时间,占用更多的内存,所以JVM更偏好更小的方法。

方法内联的前提:

  1. 方法被final修饰;
  2. 方法小。
    如果方法是经常执行的,默认情况下,方法大小小于325字节的都会进行内联(可以通过 -XX:MaxFreqInlineSize=N 来设置这个大小);
    如果方法不是经常执行的,默认情况下,方法大小小于35字节才会进行内联(可以通过-XX:MaxInlineSize=N 来设置这个大小)。

2)

这篇关于【编程素质】代码及性能优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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. 拍摄设备 相机传感器:相机传

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

MySQL高性能优化规范

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