热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ii快java_Java之深入JVM(1)由i++和++i的执行速度所想到的

iii--1i1以上的四句代码,问那句的执行速度更快?对于CC程序员来说,可能首先想到的就是i和i要比其他两者要快一些,但是在Java中是

48304ba5e6f9fe08f3fa1abda7d326ab.png

i++++i

i-=-1i+=1

48304ba5e6f9fe08f3fa1abda7d326ab.png

以上的四句代码,问那句的执行速度更快?

对于C/C++程序员来说,可能首先想到的就是i++和++i要比其他两者要快一些,但是在Java中是不是这样的呢?

我们可以对他进行一些分析,首先当然想到的是对这些语句利用Java的System.currentTimeMillis()计算单个语句运行很多次(如10亿次)后的时间,然后作比较.

例如这样:

测试环境:(1)Windows XP sp3 (2)JDK "1.6.0_07"   Client VM (build 10.0-b23, mixed

mode, sharing)

9310e85a14af99de4811ff4c77f1f911.png

24a924a57ba6b3f2b51fc9edb7ea4186.pngCodepublicclassIncrement {publicintpreIncrement() {inti=0;++i;returni;

}publicintpostIncrement() {inti=0;

i++;returni;

}publicintnegative() {inti=0;

i-=-1;returni;

}publicintplusEquals() {inti=0;

i+=1;returni;

}publicstaticvoidmain(String[] args) {

Increment in&#61;newIncrement();longstart&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.preIncrement();

}

System.out.println("preIncrement:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.postIncrement();

}

System.out.println("postIncrement:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.negative();

}

System.out.println("negative:"&#43;(System.currentTimeMillis()-start));

start&#61;System.currentTimeMillis();for(inti&#61;0; i<1000000000;

i&#43;&#43;) {

in.plusEquals();

}

System.out

.println("plusEquals:"&#43;(System.currentTimeMillis()-start));

}

}

运行结果&#xff0c;发现四次结果都不一样但是差别极其微小&#xff0c;如图:

026362f5d6206147052bc7d11d319a10.png

但是这样我们是不是就可以说&#xff0c;这四个语句的运行在Java中是有差别或者是无差别的呢&#xff1f;当然不能这样去说&#xff0c;这个程序的具体运行还受限于当前机器的所运行的其他程序以及JVM中的JIT引擎对执行代码的优化等。

其实一个比较合理的办法利用Javap反汇编这个文件&#xff0c;去看看反汇编后各个方法所生成的字节码&#xff0c;由于JVM在运行的时候就是执行这些中间代码&#xff0c;所以比较能够说明问题.

7ea6adb06a97add062cc42d178f02d3c.png

然后我运行javap –c –v

com.jni.test.tracker.object.Increment去反汇编这个代码&#xff0c;得到了preIncrement&#xff0c;postIncrement&#xff0c;negative&#xff0c;plusEquals方法各自的字节码如下&#xff1a;

public intpreIncrement();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line5: 0line6: 2line7: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intpostIncrement();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line11: 0line12: 2line13: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intnegative();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line17: 0line18: 2line19: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1i Ipublic intplusEquals();

Code:

Stack&#61;1, Locals&#61;2, Args_size&#61;1

0: iconst_01: istore_12: iinc 1, 1

5: iload_16: ireturn

LineNumberTable:

line23: 0line25: 2line26: 5LocalVariableTable:

Start Length Slot Name Signature0 7 0 this Lcom/jni/test/tracker/object/Increment;2 5 1 i I

令人惊讶的是&#xff0c;虽然这四个方法是不一样的&#xff0c;但是经过Java编译器优化后&#xff0c;我们发现生成的四个方法的bytecode实际都是一样的。

下面简单讲解一下这几句bytecode

iconst_0:将int类型的值0压入栈

istore_1: 从栈中弹出int类型值&#xff0c;然后将其存到位置为0的局部变量中

iinc 1,1 : 为局部变量中位置为1的int数 加1

iload_1 : 将局部变量中位置为1的int变量入栈

ireturn : 从栈中弹出int类型值。



推荐阅读
  • 如何搭建Java开发环境并开发WinCE项目
    本文介绍了如何搭建Java开发环境并开发WinCE项目,包括搭建开发环境的步骤和获取SDK的几种方式。同时还解答了一些关于WinCE开发的常见问题。通过阅读本文,您将了解如何使用Java进行嵌入式开发,并能够顺利开发WinCE应用程序。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • 本文介绍了使用C++Builder实现获取USB优盘序列号的方法,包括相关的代码和说明。通过该方法,可以获取指定盘符的USB优盘序列号,并将其存放在缓冲中。该方法可以在Windows系统中有效地获取USB优盘序列号,并且适用于C++Builder开发环境。 ... [详细]
author-avatar
汪健宜婉瑜
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有