`
llystar
  • 浏览: 63920 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

也说Java循环优化 (转)

 
阅读更多

最近有不少人提出 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 运行版本的区别,效率也是大不一样的

 

总结,隔了一层虚拟机,什么都有可能!

分享到:
评论

相关推荐

    Java代码循环的优化

    循环的优化设计包括数字比较尽量和0比较;尽量把异常捕获写在循环外面;尽量不要在循环内调用方法等等

    java三种循环的优化

    在java编程中,我们经常使用,但是你知道么?循环也可以优化,可以使你的程序运行的更加迅速

    Java for循环性能优化实现解析

    主要介绍了Java for循环性能优化实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    js,java提高编程效率之【for循环优化】.pdf

    js,java提高编程效率之【for循环优化】

    1Java性能优化一.zip

    所以,设计调优对系统的性能影响也是最大的,假设说,代码优化。JVM优化都是对系统微观层次的“量”的优化,那设计优化就是对系统”质”的优化. 设计优化的一大显著特征是:它能够规避某一个组件的性能问题,而是...

    Java性能优化

    Java性能优化: 1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 控制资源的使用,通过线程同步...

    Java for循环Map集合优化实现解析

    主要介绍了Java for循环Map集合优化实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    非常实用的java代码优化详解

    非常实用的java代码优化详解,从对象声明、循环、初始化 堆栈、异常等各个方面进行优化,非常有用

    算法可选择粒子群优化PSO JAVA实现整合包

    粒子群优化PSO JAVA实现整合包,可以自由调节初始化参数、对象函数、循环次数等,图形化显示算法结果。请先安装java虚拟机,添加了4种算法可选择,标准PSO,快速PSO,增活性PSO,增活性快速PSO

    java.lang.OutOfMemoryError: Java heap space 解决方法

    "Java.lang.OutOfMemoryError: Java heap space 解决...Java.lang.OutOfMemoryError: Java heap space 是一种常见的 Java 错误,解决该问题需要从多方面入手,包括调整 JVM 的堆大小、调整 Tomcat 的配置、优化程序等。

    Java循环与字符串代码优化

    本文将介绍关于Java代码中循环和字符串的优化方法,希望对读者有用。  关于循环  嵌套for循环中次数多的放在内侧,次数少的放在外侧。众所周知for循环需要定义一个循环变量来遍历每一个需要循环的对象,那么...

    粒子群优化PSO JAVA实现整合包

    粒子群优化PSO JAVA实现整合包,可以自由调节初始化参数、对象函数、循环次数等,图形化显示算法结果。请先安装java虚拟机

    java代码优化

    4、与for循环有关的性能问题 5、与集合类有关的性能问题 6、与开发有关的性能问题 7、与工具方法有关的性能问题 8、与sql动态绑定有关的性能问题 9、与反射调用有关的性能问题 10、缓存使用的性能问题 11、并发锁...

    Java实现和维护系统详解.pdf

    像这样的日志代码会更好: if (log.isLoggable(Level.FINE)) { ...关于这个主题有大量优秀的资源,相关的方法和工具也不只针对Java。假定你已经完成了分析,并且判断出是运行环境中Java 组件的性能需要改善。

    利用Idea重构功能及Java8语法特性优化深层嵌套代码

    当遇到深层嵌套代码,如for,if,lambda表达式或内部类及这些代码的组合,这时我们可以通过Java8的语法特性来进行优化。下面的代码是一个嵌套循环的示例。嵌套的for/if语句通畅可以通过Java8中的stream来替代。上述...

    Java代码优化1

    (2)缩小变量的作用范围 关于变量,尽能定义在方法内,循环体内,try…catch块内,其目的是加快GC的回收 (3)重写Exception的fillInSta

    java一次性查询处理几百万数据解决方法

    java一次性查询处理几百万数据解决方法 几百万数据是可以处理的 暂时还没试过几千万级的数据处理

    Java基础知识点总结.docx

    无论是工作学习,不断的总结是必不可少的。只有不断的总结,发现问题,弥补不足,才能长久的进步!!Java学习更是如此,知识点总结目录如下: 目录 一、 Java概述 3 二、 Java语法基础 5 ...Java 性能优化 362

    Java为改善可读性和灵活性重构代码.pdf

    关于这个主题有大量优秀的资源,相关的方法和工具也不只针对Java。假定你已经完成了分析,并且判断出是运行环境中Java 组件的性能需要改善。 ——参考资料:仅个人学习,未详尽测试,请自行调试!!

    Java编程性能优化的技巧

    使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面:第一,...3.尽量避免过多过常的创建Java对象尽量避免在经常调用的方法,循环中n

Global site tag (gtag.js) - Google Analytics