最近有不少人提出
Java
循环优化问题,问题分为两类:
1
)
for
(
int
i=0; i<10000; i--){
。。。
}
与
for
(
int
i = 100000; i > 0; i--){
。。。
}
这个比较无非是
i++
和
i—
的比较。
2
)
for
(
int
i=0; i<1000; i++) {
for
(
int
j=0; j<100000; j++) {
。。。
}
}
与
for
(
int
i = 0; i < 100000; i++) {
for
(
int
j = 0; j < 1000; j++) {
。。。
}
}
这个比较主要问题在于循环次数多的放在里面还是外面的问题。
我的观点:首先,这种代码上自以为是的优化是没有意义的;其次,拿
C
语言的思维来考虑这个问题表示
Java
基本常识都不懂。
分析:
在具体阐明我的观点前有必要做一点
Java
常识的普及。(注,若没有特别说明,文中
sun
的指的是被
Oracle
收购的那个
sun
,也用来表示
Oracle
接手的
sun
公司的一些产品,如
sun
的
jvm
,既指
Oracle
接手
sun
后的虚拟机,也指未收购时的
sun
的虚拟机)
1)
jvm
。
众所周知,这是
java
虚拟机。但是,很多人,包括初学者甚至一些工作了的人,对
jvm
的认识仅仅是
sun
的
hotspot
虚拟机,就是从
sun
官网上下载的那个。
而实际上,
sun
公司制定的是一个规范,即
Java虚拟机规范
,搜索
jvmspec
即可得。同时
sun
也提供了该规范的一个标准实现,就是
sun
的
hotspot
虚拟机(
N
年前的版本就不说了)。但很多人不知道的是,除了
sun
实现了虚拟机外,还有很多公司也根据自己的需要实现了
Java
虚拟机,比较常见的有
IBM
的
J9
(
Websphere
中用的),
Oracle
的
JRockit
(
Weblogic
中用的),
Apache
的
Harmony
(由于利益等原因,
sun
和
Oracle
都没有给它提供兼容性测试),还有
openJDK
。这些都是比较流行的。诸如此类,还有很多很多。
2)
Java
指令集
jvm
规范中,为
Java
定义了一套指令集。如
iadd
,
iinc
等,指令集用单字节表示,也就是说不超过
255
个。
关于规范中
jvm
指令集最需要注意的一点是:指令集指描述了指令该做什么事情,对于如何去做,是留给
jvm
实现者自己去思考的,所以不同的
jvm
实现对于同一段代码在效率上可能会有很大的差别。譬如,对于
iadd
指令,两个
int
相加,既可以直接交给硬件去做,也可以拐弯抹角的去做,只要最终结果符合
jvm
规范的描述即可。
3)
Java
栈
需要知道的是,
Java
考虑到跨平台的需要,所有指令的操作都不是基于寄存器的,而是内存中的
Java
栈。在
C
语言中,有个寄存器用于
pc
计数器,而在
Java
中,
pc
计数器是内存中的一个字。
Java
栈由栈帧组成,栈帧分为局部变量区,操作数栈和帧数据区。
jvm
指令的操作数大都源于操作数栈。这与一些语言从寄存器中取操作数是不同的。而局部变量区和操作数栈的大小在编译
Java
文件时就已经确定了。
对于问题一,我们有必要看一下
Java
中对于
i++
和
i—
所使用的指令
public
class
Test {
public
static
void
main(String... args) {
int
i = 0;
i++;
i--;
}
}
上面的代码编译后再用
javap –c Test
查看用到的指令:
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0:
aload_0
1:
invokespecial
#1; //Methodjava/lang/Object."<init>":()V
4:
return
public static void main(java.lang.String[]);
Code:
0:
iconst_0
1:
istore_1
2:
iinc
1, 1
5:
iinc
1, -1
8:
return
}
从上面我们发现
i++
和
i--
其实用的是同一个指令,即
iinc
,不过操作数不一样罢了;该指令直接修改局部变量区的值,而不需要压栈。至于如何去实现这个指令,不同的人在实现
jvm
的时候有自己的想法。所以问题一的比较是毫无意义的。你在
jvm
实现
1
上运行很快,可能在
jvm
实现
2
上面就运行很慢。
对于问题二,如上面普及常识所言,不同的
jvm
可以有不同的实现,不同的优化。与
C
语言不同之处在于,
java
的局部变量区在运行一个方法的时候已经分配好了,不需要遇到一个新变量就去分配。另外一点,因为由
jvm
来执行,这种循环是
jvm
内部是存在优化余地的,譬如,对于里层的循环变量,在重新下一次循环时就没用了,一些
jvm
实现就可以重用这个变量。一些
JVM
可能是纯粹的解释执行字节码,一些
JVM
可能在启动的时候就把字节码编译成
c++
本地代码,一些
jvm
可能用纯硬件芯片来执行指令集,还有一些
jvm
在运行了一段时间后找出程序热区,仔细优化并将这部分代码编译成
c++
本地代码来达到最佳效果。所有你能想到的优化都可以在这里做掉。所以不同的
jvm
实现对于这样的代码效率可能会有很大的差别。
经过本人实测(循环体是数值计算),
IBM J9 1.6
中两种都很快,
Sun hotspot
跟
J91.6
相比不是一个数量级的。但是
IBM J9 1.5
的实现则相当的慢,跟
hotspot
比慢的不是一个数量级。有兴趣的可能分别试试
openJDK
,
IBM J9
,
Jrockit
这些实现的
1.5
和
1.6
版本的效率,另外一些
jvm
还有
server
和
client
运行版本的区别,效率也是大不一样的
总结,隔了一层虚拟机,什么都有可能!
分享到:
相关推荐
循环的优化设计包括数字比较尽量和0比较;尽量把异常捕获写在循环外面;尽量不要在循环内调用方法等等
在java编程中,我们经常使用,但是你知道么?循环也可以优化,可以使你的程序运行的更加迅速
主要介绍了Java for循环性能优化实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
js,java提高编程效率之【for循环优化】
所以,设计调优对系统的性能影响也是最大的,假设说,代码优化。JVM优化都是对系统微观层次的“量”的优化,那设计优化就是对系统”质”的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是...
Java性能优化: 1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 控制资源的使用,通过线程同步...
主要介绍了Java for循环Map集合优化实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
非常实用的java代码优化详解,从对象声明、循环、初始化 堆栈、异常等各个方面进行优化,非常有用
粒子群优化PSO JAVA实现整合包,可以自由调节初始化参数、对象函数、循环次数等,图形化显示算法结果。请先安装java虚拟机,添加了4种算法可选择,标准PSO,快速PSO,增活性PSO,增活性快速PSO
"Java.lang.OutOfMemoryError: Java heap space 解决...Java.lang.OutOfMemoryError: Java heap space 是一种常见的 Java 错误,解决该问题需要从多方面入手,包括调整 JVM 的堆大小、调整 Tomcat 的配置、优化程序等。
本文将介绍关于Java代码中循环和字符串的优化方法,希望对读者有用。 关于循环 嵌套for循环中次数多的放在内侧,次数少的放在外侧。众所周知for循环需要定义一个循环变量来遍历每一个需要循环的对象,那么...
粒子群优化PSO JAVA实现整合包,可以自由调节初始化参数、对象函数、循环次数等,图形化显示算法结果。请先安装java虚拟机
4、与for循环有关的性能问题 5、与集合类有关的性能问题 6、与开发有关的性能问题 7、与工具方法有关的性能问题 8、与sql动态绑定有关的性能问题 9、与反射调用有关的性能问题 10、缓存使用的性能问题 11、并发锁...
像这样的日志代码会更好: if (log.isLoggable(Level.FINE)) { ...关于这个主题有大量优秀的资源,相关的方法和工具也不只针对Java。假定你已经完成了分析,并且判断出是运行环境中Java 组件的性能需要改善。
当遇到深层嵌套代码,如for,if,lambda表达式或内部类及这些代码的组合,这时我们可以通过Java8的语法特性来进行优化。下面的代码是一个嵌套循环的示例。嵌套的for/if语句通畅可以通过Java8中的stream来替代。上述...
(2)缩小变量的作用范围 关于变量,尽能定义在方法内,循环体内,try…catch块内,其目的是加快GC的回收 (3)重写Exception的fillInSta
java一次性查询处理几百万数据解决方法 几百万数据是可以处理的 暂时还没试过几千万级的数据处理
无论是工作学习,不断的总结是必不可少的。只有不断的总结,发现问题,弥补不足,才能长久的进步!!Java学习更是如此,知识点总结目录如下: 目录 一、 Java概述 3 二、 Java语法基础 5 ...Java 性能优化 362
关于这个主题有大量优秀的资源,相关的方法和工具也不只针对Java。假定你已经完成了分析,并且判断出是运行环境中Java 组件的性能需要改善。 ——参考资料:仅个人学习,未详尽测试,请自行调试!!
使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:第一,...3.尽量避免过多过常的创建Java对象尽量避免在经常调用的方法,循环中n