慎用异常

在java中,经常使用try_catch进行异常捕获,但是try-catch语言对系统是非常糟糕的。虽然一次try-catch中,无法察觉到它对性能带来的损失,但是一旦try-catch用于循环中,就会给系统带来巨大的损害.

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int a = 0;
for (int i = 0; i < 10000000; i++) {
try {
a++;
} catch (Exception e) {
}
}1
System.out.println("Cost time :" + (System.currentTimeMillis() - startTime));
}

如果尝试将try-catch移到外部,那么就能提升系统性能代码:

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int a = 0;
try {
for (int i = 0; i < 1000000000; i++) {
a++;
}
} catch (Exception e) {
}
System.out.println("Cost time :" + (System.currentTimeMillis() - startTime));
}

使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈(Stack)中,速度较快,其他变量,如静态变量,实例变量等,都在堆(Heap)中创建,速度较慢.

1
2
3
4
5
6
7
8
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int a = 0;
for (int i = 0; i < 1000000000; i++) {
a++;
}
System.out.println("Cost time :" + (System.currentTimeMillis() - startTime));
}

Cost time :3

1
2
3
4
5
6
7
8
9
public static int FLAG = 0;
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
FLAG++;
}
System.out.println("Cost time :" + (System.currentTimeMillis() - startTime));
}

Cost time :62

由此可见,局部变量的访问速度远远高于累的成员变量

位运算代替乘除法

在所有运算中,位运算是最高效的.因此,可以尝试使用位运算代替部分算数运算,来提高运行速度,最典型的就是对于整数的乘除运算优化.

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long a = 100;
for (int i = 0; i < 1000000000; i++) {
a *= 2;
a /= 2;
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:1401

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long a = 100;
for (int i = 0; i < 1000000000; i++) {
a <<= 1;
a >>= 1;
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:69
两段代码执行了完全相同的功能但是第一段耗时1401毫秒第二段只要69毫秒

提取表达式

在开发过程中,程序员很容易有意无意地让代码做一些”重复劳动”,在大部分的情况下,由于计算机的高速运行,这些”重复劳动”并不会对性能构成太大的威胁,但是若希望洗能发挥到极致,
提取这些”重复劳动”相当有意义.
eg:

1
2
3
4
5
6
7
8
9
10
11
long startTime = System.currentTimeMillis();
double a = Math.random();
double b = Math.random();
double d = Math.random();
double e = Math.random();
double x, y;
for (int i = 0; i < 1000000000; i++) {
x = d * a * b / 3 * 4 * a;
y = e * a * b / 3 * 4 * a;
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));

cost time:10

1
2
3
4
5
6
7
8
9
10
11
12
long startTime = System.currentTimeMillis();
double a = Math.random();
double b = Math.random();
double d = Math.random();
double e = Math.random();
double t, x, y;
for (int i = 0; i < 1000000000; i++) {
t = a * b / 3 * 4 * a;
x = d * t;
y = e * t;
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));

cost time:5

布尔运算代替位运算

1
2
3
4
5
6
7
8
9
10
11
12
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
boolean a = false;
boolean b = true;
int d = 0;
for (int i = 0; i < 1000000000; i++) {
if (a & b & "Java_per".contains("Java")) {
d = 0;
}
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:4560

1
2
3
4
5
6
7
8
9
10
11
12
13
14
数据复制是一项使用评率很高的功能,JDK中提供了一个搞笑的API arraycopy 来实现它
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
boolean a = false;
boolean b = true;
int d = 0;
for (int i = 0; i < 1000000000; i++) {
if (a && b && "Java_per".contains("Java")) {
d = 0;
}
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:2

简单的来说,在布尔表达式中,只要表达式的值可以确定,就立即返回,而跳过去他的表达式计算.

使用System.arraycopy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
int size = 100000;
int[] array = new int[size];
int[] arraydst = new int[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
long startTime = System.currentTimeMillis();
for (int k = 0; k < 1000; k++) {
System.arraycopy(array, 0, arraydst, 0, size);
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:32

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public static void main(String[] args) {
int size = 100000;
int[] array = new int[size];
int[] arraydst = new int[size];
for (int i = 0; i < array.length; i++) {
array[i] = i;
}
long startTime = System.currentTimeMillis();
for (int k = 0; k < 1000; k++) {
for (int i = 0; i < size; i++) {
arraydst[i] = array[i];
}
}
System.out.println("cost time:" + (System.currentTimeMillis() - startTime));
}

cost time:71

System.arraycopy()函数是native函数,通常native函数性能要优于普通的函数,仅出于性能考虑,在软件开发时,应经可能调用native函数.