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

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

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码

《在MyBatis的XML映射文件中<trim>元素所有场景下的完整使用示例代码》在MyBatis的XML映射文件中,trim元素用于动态添加SQL语句的一部分,处理前缀、后缀及多余的逗号或连接符,示... 在MyBATis的XML映射文件中,<trim>元素用于动态地添加SQL语句的一部分,例如SET或W

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

python多进程实现数据共享的示例代码

《python多进程实现数据共享的示例代码》本文介绍了Python中多进程实现数据共享的方法,包括使用multiprocessing模块和manager模块这两种方法,具有一定的参考价值,感兴趣的可以... 目录背景进程、进程创建进程间通信 进程间共享数据共享list实践背景 安卓ui自动化框架,使用的是

SpringBoot生成和操作PDF的代码详解

《SpringBoot生成和操作PDF的代码详解》本文主要介绍了在SpringBoot项目下,通过代码和操作步骤,详细的介绍了如何操作PDF,希望可以帮助到准备通过JAVA操作PDF的你,项目框架用的... 目录本文简介PDF文件简介代码实现PDF操作基于PDF模板生成,并下载完全基于代码生成,并保存合并P