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

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

相关文章

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Spring Boot 3.4.3 基于 Spring WebFlux 实现 SSE 功能(代码示例)

《SpringBoot3.4.3基于SpringWebFlux实现SSE功能(代码示例)》SpringBoot3.4.3结合SpringWebFlux实现SSE功能,为实时数据推送提供... 目录1. SSE 简介1.1 什么是 SSE?1.2 SSE 的优点1.3 适用场景2. Spring WebFlu

java之Objects.nonNull用法代码解读

《java之Objects.nonNull用法代码解读》:本文主要介绍java之Objects.nonNull用法代码,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录Java之Objects.nonwww.chinasem.cnNull用法代码Objects.nonN

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

一文详解SpringBoot响应压缩功能的配置与优化

《一文详解SpringBoot响应压缩功能的配置与优化》SpringBoot的响应压缩功能基于智能协商机制,需同时满足很多条件,本文主要为大家详细介绍了SpringBoot响应压缩功能的配置与优化,需... 目录一、核心工作机制1.1 自动协商触发条件1.2 压缩处理流程二、配置方案详解2.1 基础YAML

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.