JDK源码中为什么在方法中创建一个临时变量替代成员变量、类变量 又名 临时变量提高Java代码性能
一个Java类中可以存在多种形式的变量,可以是最一般的成员变量;或静态变量;或临时变量。那么这三种变量的存取效率如何?
1、实战出真知
```java
package com.subject.variable;
/**
* 使用临时变量提高Java代码性能 (转)
*/
public class VariableDemo {
private long instVar;// 成员变量
private static long staticVar; // 静态变量
// 存取类方法中的临时变量
void tempAccess(long val) {
int j = 0;// 临时变量
long startTime = System.currentTimeMillis();
for (long i = 0; i < val; i++) {
j += 1;
}
long endTime = System.currentTimeMillis();
System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
}
// 存取类的成员变量
void instanceAccess(long val) {
long startTime = System.currentTimeMillis();
for (long i = 0; i < val; i++) {
instVar += 1;
}
long endTime = System.currentTimeMillis();
System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
}
// 存取类的 static 变量
void staticAccess(long val) {
long startTime = System.currentTimeMillis();
for (long i = 0; i < val; i++) {
staticVar += 1;
}
long endTime = System.currentTimeMillis();
System.out.println("static var: " + (endTime - startTime) + " milli seconds");
}
public static void main(String[] args) {
VariableDemo test = new VariableDemo();
long count=10*1000*1000*1000L;
test.tempAccess(count);
test.instanceAccess(count);
test.staticAccess(count);
}
}
计算结果:
```java
temp var: 2987 milli seconds
instance var: 4039 milli seconds
static var: 3996 milli seconds
这段代码中的每个方法都执行相同的循环,并反复相同的次数。唯一的不同是每个循环使一个不同类型的变量递增。方法 tempAccess 使一个局部堆栈变量递增,instanceAccess 使类的一个成员实例变量递增,而 staticAccess 使类的一个 static 变量递增。
从结果中可以发现,instanceAccess 和 staticAccess 的执行时间基本相同。但是,tempAccess 要快两到三倍。
2、JVM存取变量机制
存取堆栈变量如此快是因为JVM 存取堆栈变量比它存取 成员变量 或 静态变量执行的操作少。
JVM 是一种基于堆栈的虚拟机,因此优化了对堆栈数据的存取和处理。所有局部变量都存储在一个局部变量表中,在 Java 操作数堆栈中进行处理,并可被高效地存取。
存取 成员变量 和 静态变量 成本更高,因为 JVM 必须使用代价更高的操作码,并从常数存储池中存取它们。(常数存储池保存一个类型所使用的所有类型、字段和方法的符号引用。)通常,在第一次从常数存储池中访问 static 变量或实例变量以后,JVM 将动态更改字节码以使用效率更高的操作码。尽管有这种优化,堆栈变量的存取仍然更快。
3、那么如何优化代码
考虑到这些事实,就可以重新构建前面的代码,以便通过存取堆栈变量而不是实例变量或 static 变量使操作更高效。
package com.subject.variable;
/**
* 使用临时变量提高Java代码性能 (转)
*/
public class VariableDemo2 {
private long instVar;// 成员变量
private static long staticVar; // 静态变量
// 存取类方法中的临时变量
void tempAccess(long val) {
int j = 0;// 临时变量
long startTime = System.currentTimeMillis();
for (long i = 0; i < val; i++) {
j += 1;
}
long endTime = System.currentTimeMillis();
System.out.println("temp var: " + (endTime - startTime) + " milli seconds");
}
// 存取类的成员变量
void instanceAccess(long val) {
long startTime = System.currentTimeMillis();
long tmp=instVar;
for (long i = 0; i < val; i++) {
tmp += 1;
}
instVar=tmp;
long endTime = System.currentTimeMillis();
System.out.println("instance var: " + (endTime - startTime) + " milli seconds");
}
// 存取类的 static 变量
void staticAccess(long val) {
long startTime = System.currentTimeMillis();
long tmp=staticVar;
for (long i = 0; i < val; i++) {
tmp += 1;
}
staticVar=tmp;
long endTime = System.currentTimeMillis();
System.out.println("static var: " + (endTime - startTime) + " milli seconds");
}
public static void main(String[] args) {
VariableDemo2 test = new VariableDemo2();
long count=10*1000*1000*1000L;
test.tempAccess(count);
test.instanceAccess(count);
test.staticAccess(count);
}
}
计算结果:
temp var: 2973 milli seconds
instance var: 3074 milli seconds
static var: 3018 milli seconds
转载来源
http://blog.csdn.net/yejin191258966/article/details/40195933
原文样式已经凌乱了,特重新进行了整理,并统一了术语,比如实例变量/成员变量,静态变量/static变量
————————————————
版权声明:本文为CSDN博主「明月(Alioo)」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hl_java/article/details/79288909