Java性能优化的十条小技巧
1 System.nanoTime
测试性能时,System.nanoTime
比System.currentTimeMills
更精确,前者使用纳秒计时,且对系统影响更小。
具体来说:
System.currentTimeMills
返回自1970年1月1日
以来经过的毫秒数,返回的精度与操作系统有关System.nanoTime
:不是现实时间,是虚拟机提供的计时时间,精确到纳秒
2 ThreadLocalRandom
通常生成随机数会使用Random
类,Random
是线程安全的,Random
实例里面有一个原子性的种子变量来记录当前种子的值,当要生成新的随机数时,会根据当前种子计算新的种子并更新回原子变量。多线程下计算新种子,会竞争同一个原子变量的更新操作,会造成大量线程进行自旋测试,降低并发性能。
而ThreadLocalRandom
在当前线程维护了一个种子,适合在多线程场景下提供高性能的伪随机数生成,使用如下:
ThreadLocalRandom random = ThreadLocalRandom.current();
random.nextInt(range);
3 使用局部变量
理论上说,访问局部变量会快于类变量,因为局部变量保存在方法栈中,而类变量保存在堆中。如果在某个类方法中需要多次访问类变量,建议先创建一个局部变量并使其具有与类变量相同的值。
4 关于正则表达式替换
由于正则表达式替换时每次都需要编译正则表达式到一个中间结构,因此比常规的直接替换要慢,如果是固定的正则表达式替换,可以采用预编译的思想:
Pattern pattern = Pattern.compile("origin str");
public String replace(String str){
return pattern.matcher(str).replaceAll("target str");
}
而不是采用:
public String replace(String str){
return str.replace("origin str","target str");
}
5 关于字符串拼接
尽可能使用如下形式:
String a = "xxx";
String b = "xxx";
String c = new StringBuilder().append(a).append(b).toString();
性能相对不好的是如下情形(得益于JVM
默认开启字符串拼接优化):
String c = a+b;
性能最差的是:
StringBuilder c = new StringBuilder();
c.append(a);
c.append(b);
String result = c.toString();
因为这样JIT
不会优化。
另外,在无关线程安全的情况下,尽可能使用StringBuilder
而不是StringBuffer
。
6 关于数字转字符串
int
转String
是一个较为耗时的操作,尽量避免不必要的转化,如果确实需要,可以预先将一批int
转为String
,需要的时候直接取出:
public static class CommonUtil{
static int cacheSize = 1024;
static String [] caches = new String[cacheSize];
static{
for(int i=0;i<cacheSize;++i){
caches[i] = String.valueOf(i);
}
}
public static String int2String(int data){
if(data < cacheSize){
return caches[size];
}else{
return String.valueOf(data);
}
}
}
这样相比起直接使用
Stirng.valueOf(data)
性能会高一点。
7 switch
/if
少分支的情况下,建议使用if
,多分支建议使用switch
,常用的“少分支”标准是2-5个
。
8 采用返回码而不是抛异常
除非必要使用异常,应该避免把正常的返回错误结果使用异常来代替。抛异常会导致性能是因为构造异常对象时需要一个填写异常栈的过程,就是Throwable
中的fillInStackTrace
,这是一个Native
方法,会填写异常栈,造成较为严重的耗时。
一种优化方法是,自定义异常,重写fillInStackTrace()
:
public class MyException extends RuntimeException{
...
public synchronized Throwable fillInStackTrace(){
this.setStackTrace(new StackTraceElement[0]);
return this;
}
}
另外,JVM
会对频繁抛出的异常做Fast Throw
优化,如果检测到代码中某一位置连续多次抛出同一类型的异常,则采用Fast Throw
方式,异常栈信息不会被填写,这种异常抛出速度很快,因为不需要在堆里分配内存,也不需要构造完整的异常栈信息,默认对如下异常采用Fast Throw
优化:
NullPointerException
ArithmeticException
ArrayIndexOutOfBoundsExpcetion
ArrayStoreException
ClassCastException
需要注意的是,Fast Throw
虽然提高了性能,但是会导致异常栈消息,从而无法快速定位到错误代码,如果需要避免异常栈优化,可以使用参数:
-XX:-OmitStackTraceInFastThrow
9 位运算
可以通过位运算代替部分算术运算以提高性能,比如:
- 判断奇数:
(a & 1) == 1
- 判断偶数:
(a & 1) == 0
- 除2:
a>>1
- 乘2:
a<<1
10 其他技巧
- 字符串搜索等需要搜索单个字符时,使用
String.indexOf(char)
而不是String.indexOf(String)
- 对于判断一些特殊的
ID
,比如长度9位
且以11
开头,可以直接使用常数判断:id>=110_000_000 && id<=120_000_000
,而不需要通过String.valueOf
转为字符串再通过String.length
+String.startWith
判断 - 在
switch
中,可以使用int
去代替String
- 日志输出可以直接使用字符串拼接而不是
模板+{}
,因为会有一个占位符{}
替换成目标变量的耗时过程,被频繁调用的话建议直接字符串拼接 - 传输的实体类尽量避免使用
String
,因为其中涉及序列化、反序列化、字符串构造,而对于byte[]
构造String
的方法,内部会调用StringCoding.decode
,相比起通过char[]
/Stirng
构造会造成更大的耗时
Java性能优化的十条小技巧的更多相关文章
- UITableView的性能优化10个小技巧
通常你会发现一个图片类的app会在一个imageView上做下面这些事情: 1 下载图片(主要的内容图片+用户头像图片)2 更新时间戳3 展示评论4 计算动态的cell的高度 Tip#1 学习 ...
- iOS-UITableView的性能优化10个小技巧
通常你会发现一个图片类的app会在一个imageView上做下面这些事情: 1 下载图片(主要的内容图片+用户头像图片)2 更新时间戳3 展示评论4 计算动态的cell的高度 Tip#1 学习 ...
- Java 性能优化手册 — 提高 Java 代码性能的各种技巧
转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...
- Java 性能优化的五大技巧
要对你的 Java 代码进行优化,需要理解 Java 不同要素之间的相互作用,以及它是如何与其运行时的操作系统进行交互的.使用下面这五个技巧和资源,开始学习如何分析和优化你的代码吧. 在我们开始之前, ...
- 《Java性能优化权威指南》
<Java性能优化权威指南> 基本信息 原书名:Java performance 原出版社: Addison-Wesley Professional 作者: (美)Charlie Hunt ...
- 推荐:Java性能优化系列集锦
Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...
- 【转】10种简单的Java性能优化
10种简单的Java性能优化 2015/06/23 | 分类: 基础技术 | 14 条评论 | 标签: 性能优化 分享到: 本文由 ImportNew - 一直在路上 翻译自 jaxenter.欢迎加 ...
- 44个Java性能优化
44个Java性能优化 首先,代码优化的目标是: 减小代码的体积 提高代码运行效率 代码优化细节 1 .尽量指定类.方法的final修饰符 带有final修饰符的类是不可派生的.在Java核心AP ...
- java 性能优化(代码优化)
参考博文: java 性能优化:35 个小细节,让你提升 java 代码的运行效率
随机推荐
- (转载)VoLTE简介
转载地址:http://www.360doc.cn/article/2909773_637471256.html,本文介绍了移动通信领域相关概念,如CS.PS.VoIP.VoLTE.IMS.CSFB. ...
- 从微信小程序到鸿蒙js开发【08】——表单组件&注册登录模块
目录: 1.登录模块 2.注册模块 3.系列文章导读 牛年将至,祝大家行行无bug,页页so easy- 在微信小程序中,提供了form组件,可以将input.picker.slider.button ...
- JAVA 批量下载服务器文件到本地指定文件夹并重命名
/** * @功能 下载文件到指定文件夹并重命名 * @param url 请求的路径 * @param filePath 文件将要保存的目录 * @param filename 保存到本地的文件名 ...
- java中是否存在i+1<i?
存在! 首先我们知道int的取值范围是: -2147483648~2147483647,最高位为符号位 2147483647的二进制为:01111111 11111111 11111111 11111 ...
- JVM相关 - 深入理解 System.gc()
本文基于 Java 17-ea,但是相关设计在 Java 11 之后是大致一样的 我们经常在面试中询问 System.gc() 究竟会不会立刻触发 Full GC,网上也有很多人给出了答案,但是这些答 ...
- springboot项目打包成jar包在Linux服务器默认80端口运行
springboot项目端口设置 在application.properties文件 server.port=80 在application.yml文件 server: port: 80 然后在ide ...
- java与freemarker遍历map
一.java遍历MAP /** * 1.把key放到一个集合里,遍历key值同时根据key得到值 (推荐) */ Set set =map.keySet(); Iterator it=set.iter ...
- spring boot的 yml和properties的对比
Spring Boot 虽然做了大量的工作来简化配置,但其配置依然是相当的复杂!支持的外部配置方式就有很多种,笔者没有去统计,也许是为了灵活使用吧. application.yml 和 appli ...
- Django框架admin后台管理和用户端静态文件
目录 一.admin后台管理 1. 如何使用 2. 路由分发的本质 二.用户上传的静态文件的展示 1. media配置 2. 手动开设media接口 三.图片防盗链 一.admin后台管理 djang ...
- 在 Svelte 中使用 CSS-in-JS
你即便不需要,但你可以. 注意:原文发表于2018-12-26,随着框架不断演进,部分内容可能已不适用. CSS 是任何 Web 应用程序的核心部分. 宽泛而论,如果一个 UI 框架没有内置向组件添加 ...