1 System.nanoTime

测试性能时,System.nanoTimeSystem.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 关于数字转字符串

intString是一个较为耗时的操作,尽量避免不必要的转化,如果确实需要,可以预先将一批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性能优化的十条小技巧的更多相关文章

  1. UITableView的性能优化10个小技巧

    通常你会发现一个图片类的app会在一个imageView上做下面这些事情: 1  下载图片(主要的内容图片+用户头像图片)2  更新时间戳3  展示评论4  计算动态的cell的高度 Tip#1 学习 ...

  2. iOS-UITableView的性能优化10个小技巧

    通常你会发现一个图片类的app会在一个imageView上做下面这些事情: 1  下载图片(主要的内容图片+用户头像图片)2  更新时间戳3  展示评论4  计算动态的cell的高度 Tip#1 学习 ...

  3. Java 性能优化手册 — 提高 Java 代码性能的各种技巧

    转载: Java 性能优化手册 - 提高 Java 代码性能的各种技巧 Java 6,7,8 中的 String.intern - 字符串池 这篇文章将要讨论 Java 6 中是如何实现 String ...

  4. Java 性能优化的五大技巧

    要对你的 Java 代码进行优化,需要理解 Java 不同要素之间的相互作用,以及它是如何与其运行时的操作系统进行交互的.使用下面这五个技巧和资源,开始学习如何分析和优化你的代码吧. 在我们开始之前, ...

  5. 《Java性能优化权威指南》

    <Java性能优化权威指南> 基本信息 原书名:Java performance 原出版社: Addison-Wesley Professional 作者: (美)Charlie Hunt ...

  6. 推荐:Java性能优化系列集锦

    Java性能问题一直困扰着广大程序员,由于平台复杂性,要定位问题,找出其根源确实很难.随着10多年Java平台的改进以及新出现的多核多处理器,Java软件的性能和扩展性已经今非昔比了.现代JVM持续演 ...

  7. 【转】10种简单的Java性能优化

    10种简单的Java性能优化 2015/06/23 | 分类: 基础技术 | 14 条评论 | 标签: 性能优化 分享到: 本文由 ImportNew - 一直在路上 翻译自 jaxenter.欢迎加 ...

  8. 44个Java性能优化

    44个Java性能优化 首先,代码优化的目标是: 减小代码的体积 提高代码运行效率 代码优化细节 1 .尽量指定类.方法的final修饰符 ​ 带有final修饰符的类是不可派生的.在Java核心AP ...

  9. java 性能优化(代码优化)

    参考博文: java 性能优化:35 个小细节,让你提升 java 代码的运行效率

随机推荐

  1. Redis 日志篇:系统高可用的杀手锏

    特立独行是对的,融入圈子也是对的,重点是要想清楚自己向往怎样的生活,为此愿意付出怎样的代价. 我们通常将 Redis 作为缓存使用,提高读取响应性能,一旦 Redis 宕机,内存中的数据全部丢失,假如 ...

  2. python中的enumerate 函数(编号的实现方式)

    enumerate 函数用于遍历序列中的元素以及它们的下标: 默认从0开始,如果想从1开始,可以仿照最后案例 加上逗号,和数字编号 >>> for i,j in enumerate( ...

  3. tesseract-ocr和tesseract.exe is not installed or it's not in your path问题解决

    一.解决方案: 1.http://www.ddooo.com/softdown/94968.htm   打开下载的压缩包,找到"tesseract-ocr-setup-3.02.02.exe ...

  4. 阿里巴巴Druid,轻松实现MySQL数据库连接加密!

    为什么要加密? 现在的开发习惯,无论是公司的项目还是个人的项目,都会选择将源码上传到 Git 服务器(GitHub.Gitee 或是自建服务器),但只要将源码提交到公网服务器就会存在源码泄漏的风险,而 ...

  5. windows上传ipa文件到苹果开发者中心的教程

    转: windows上传ipa文件到苹果开发者中心的教程 我们在苹果开发者中心上架ios app的时候,需要使用xcode或transporter先上传ipa文件到开发者中心. 但是假如我们只是H5开 ...

  6. CVE-2017-7504-JBoss JMXInvokerServlet 反序列化

    漏洞分析 https://paper.seebug.org/312/ 漏洞原理 这是经典的JBoss反序列化漏洞,JBoss在/invoker/JMXInvokerServlet请求中读取了用户传入的 ...

  7. 三分钟教你提升应用推送的ROI

    推送是App应用性价比最高也是最直接的营销运营手段,其细节颇多,非常考验运营人员的功力,本文将从ROI角度来分析怎么提升营销类推送的收益.(非IM类.系统类等功能服务型推送) 以一个日活100万的应用 ...

  8. P3796 【模板】AC自动机(加强版) 题解(Aho-Corasick Automation)

    题目链接 AC自动机 解题思路 AC自动机模板题. 刚学AC自动机,写一篇博客增强理解. AC自动机最关键的一点在于,\(fail\)失配指针的构造. \(fail\)指针指向的地方,是匹配出现错误后 ...

  9. MySQL入门(4)——操作数据表

    MySQL入门(4)--操作数据表 创建数据库 CREATE [TEMPORARY] TABLE [IF NOT EXISTS] 数据库名 [(create_definition,...)] [tab ...

  10. java 动态规划解决最大连续子数列和

    很多动态规划算法非常像数学中的递推.我们如果能找到一个合适的递推公式,就能很容易的解决问题.我们用dp[n]表示以第n个数结尾的最大连续子序列的和,这里第n个数必须在子序列中.于是存在以下递推公式: ...